{"id":34191588,"url":"https://github.com/alphauslabs/jupiter","last_synced_at":"2026-03-12T06:40:25.109Z","repository":{"id":189277004,"uuid":"680389927","full_name":"alphauslabs/jupiter","owner":"alphauslabs","description":"A highly scalable Redis mini-clone for caching mainly Ripple/WavePro's graph and reports data.","archived":false,"fork":false,"pushed_at":"2024-11-25T23:48:10.000Z","size":623,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-12-18T16:07:07.025Z","etag":null,"topics":["cache","redis-proxy"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alphauslabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-19T05:01:59.000Z","updated_at":"2024-11-25T23:48:14.000Z","dependencies_parsed_at":"2023-09-27T13:16:03.327Z","dependency_job_id":"b5a6fb7c-ae7d-41f5-8601-185defc1cbce","html_url":"https://github.com/alphauslabs/jupiter","commit_stats":null,"previous_names":["alphauslabs/eris","alphauslabs/jupiter"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alphauslabs/jupiter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphauslabs%2Fjupiter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphauslabs%2Fjupiter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphauslabs%2Fjupiter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphauslabs%2Fjupiter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alphauslabs","download_url":"https://codeload.github.com/alphauslabs/jupiter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphauslabs%2Fjupiter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30417543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T04:41:02.746Z","status":"ssl_error","status_checked_at":"2026-03-12T04:40:12.571Z","response_time":114,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","redis-proxy"],"created_at":"2025-12-15T16:03:38.238Z","updated_at":"2026-03-12T06:40:25.077Z","avatar_url":"https://github.com/alphauslabs.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"**NOTE: This project is already deprecated.**\n\n---\n\n`jupiter` is our custom, highly-scalable [Redis](https://redis.io/) mini-clone specifically designed as cache for our graph and reports data. It acts as a proxy to a cluster of Redis (in our case, [Memorystore](https://cloud.google.com/memorystore)) nodes and handles load distribution using [consistent hashing](https://en.wikipedia.org/wiki/Consistent_hashing). Sort of similar to [Envoy Redis proxy](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_protocols/redis). It supports (WIP) dynamic addition and removal of Redis nodes with minimal interruptions.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/jupiter.png\" width=\"560\" title=\"hedge\"\u003e\n\u003c/p\u003e\n\n`jupiter` is not a Redis replacement, although it is compatible with most Redis clients such as [`redigo`](https://github.com/gomodule/redigo) and [`go-redis`](https://github.com/redis/go-redis). It is a best-effort caching system, prioritizing availability over consistency.\n\nThere is a slight performance penalty over direct connections to Redis due to its use of hashing; it requires all commands to have a key as hash to find the corresponding Redis node. If you require high performance caching, you're probably better off using a dedicated Redis node/cluster.\n\n### Why\n\nThe main reason why `jupiter` exists is that at the time of this writing, the maximum Memorystore instance available in GCP is 300GB. Beyond this, we need to create more instances. Instead of leaving the responsibility of accessing multiple Memorystore instances to our applications, it's more convenient to be able to access these clusters of instances as a single entity. After a trial run with [Envoy Redis proxy](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/other_protocols/redis), we wanted something more, especially the ability to add/remove instances seamlessly with minimal interruptions to our client applications. [Redis Ring](https://redis.uptrace.dev/guide/ring.html) was also considered but we wanted more control and flexibility on the control plane side.\n\n### Hashing\n\nMost of the \"caching\" commands in Redis need a key (usually `args[1]`, or the argument after the command itself). `jupiter` will try to use this argument as the default hashing key. This renders some other Redis commands unsupported, such as cluster commands, Pub/Sub, transactions, LUA scripting, etc. However, `jupiter` also provides a custom way to input a (or override the) hashing key if needed **using the last argument**.\n\nAdding the `hash={key}` argument at the end of a command tells `jupiter` to use `{key}` as the hash key. This argument won't be included in the final Redis command that is submitted to the target node.\n\nFor example:\n\n```sh\n# Use 'somekey' as the hashing key.\nredis\u003e SET hello world hash=somekey\nredis\u003e GET hello hash=somekey\n\n# Here, jupiter will use 'hello' as the hashing key.\nredis\u003e SET hello world\nredis\u003e GET hello\n\n# For scans, you most definitely want to provide the hash.\nredis\u003e MSET key1 val1 key2 val2 key3 val3 hash=somekey\n\"OK\"\nredis\u003e SCAN 0 MATCH key* hash=somekey\n1) \"0\"\n2) 1) \"key3\"\n   2) \"key2\"\n   3) \"key1\"\n```\n\nFinally, `jupiter` will use a random hash key if none is detected/provided. For example, commands with no arguments such as `DBSIZE`, `TIME`, `RANDOMKEY`, etc.\n\n### Usage\n\nUsing [`go-redis`](https://github.com/redis/go-redis) (recommended):\n\n```go\n// You can use the `jupiter` package in ouchan:\nimport (\n    ...\n    \"github.com/mobingilabs/ouchan/pkg/jupiter\"\n)\n\njupiter.Init()\n...\nctx := context.Background()\n_, err := jupiter.Client().Set(ctx, \"key\", \"value\", time.Second*10).Result()\nif err != nil {\n    // failed\n} else {\n    // ok\n}\n```\n\nUsing [`redigo`](https://github.com/gomodule/redigo):\n\n```go\nimport (\n    ...\n    \"github.com/gomodule/redigo/redis\"\n)\n\nhashKey := \"hash=sample/hashkey\"\npool := \u0026redis.Pool{\n    MaxIdle:     3,\n    MaxActive:   100,\n    IdleTimeout: 240 * time.Second,\n    Dial: func() (redis.Conn, error) {\n        return redis.Dial(\"tcp\", \"jupiter-redis.default.svc.cluster.local:6379\")\n    },\n}\n\ncon := pool.Get()\ndefer con.Close()\nv, err := redis.String(con.Do(\"PING\", hashKey))\nif err != nil {\n    log.Printf(\"PING failed: %v\", err)\n} else {\n    log.Printf(\"reply=%v\", v)\n}\n```\n\n### Try it out (internal)\n\nIf you want to try `jupiter` using `redis-cli`, you can do so by:\n\n```sh\n# Do a port-forward of the prod service to your local (separate terminal):\n$ brew install flowerinthenight/tap/kubepfm\n$ kubepfm --target service/jupiter-redis:6379:6379\n\n# Connect redis-cli to the forwarded port (separate terminal):\n$ redis-cli\n127.0.0.1:6379\u003e PING hash=somekey\n\"PONG\"\n127.0.0.1:6379\u003e quit\n```\n\n### Limitations\n\nPipelining and transactions are not supported as `jupiter` doesn't guarantee the use of a single connection for multiple, related commands (i.e. `MULTI`, `...`, `EXEC`), even if the same hash key is provided. We might support these in future versions.\n\n### Notes\n\n`jupiter` is a very GCP-centric system; it uses [`hedge`](https://github.com/flowerinthenight/hedge) as its cluster coordinator which requires [Cloud Spanner](https://cloud.google.com/spanner).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falphauslabs%2Fjupiter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falphauslabs%2Fjupiter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falphauslabs%2Fjupiter/lists"}