尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证A distributed, in-memory key-value store built to make distributed-systems behavior tangible.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A distributed, in-memory key-value store built to make distributed-systems behavior tangible. Shardis implements sharding, leader–follower replication, durable writes, failover, live slot migration, pub/sub, and cluster observability using real processes and WebSocket connections.
It is intentionally a small-scale learning and demonstration system—not a Redis replacement. The goal is readable implementation, honest trade-offs, and reproducible failure testing.查看完整 README ↗A distributed, in-memory key-value store built to make distributed-systems behavior tangible. Shardis implements sharding, leader–follower replication, durable writes, failover, live slot migration, pub/sub, and cluster observability using real processes and WebSocket connections.
It is intentionally a small-scale learning and demonstration system—not a Redis replacement. The goal is readable implementation, honest trade-offs, and reproducible failure testing.
/healthz · follower /healthzFree Render services sleep after idle traffic and can take about a minute to wake. The dashboard retries automatically and shows a waking state during that interval.
MOVED redirects, and ASK redirects while slots migrate.fsync before acknowledgement, snapshots, compaction, replay, and crash recovery.SIGKILL recovery and Compose smoke tests in CI. ┌─────────────────────┐
│ Dashboard / CLI │
│ WebSocket clients │
└──────────┬──────────┘
│
MOVED / ASK │ GET · SET · DEL · PUB/SUB
▼
┌───────────────────────────────────────────────────┐
│ Shardis cluster │
│ │
│ Shard A Shard B Shard C │
│ a1 (leader) ──► a2 b1 (leader) ──► b2 c1 ──► c2│
│ │ │ │ │
│ AOF + snapshot AOF + snapshot AOF + snapshot
└───────────────────────────────────────────────────┘
The local environment runs three shards and six nodes. Any node can accept a client connection; when a key belongs elsewhere, the client is redirected to the active leader for that shard.
pnpm install
pnpm build
pnpm test
docker compose up -d --build
curl http://localhost:7001/healthz
The six nodes are exposed on ports 7001–7006. Stop the cluster and remove its local volumes with:
docker compose down -v
pnpm --filter @shardis/cli build
node packages/cli/dist/shardis-cli.js --url ws://localhost:7001/ws SET hello world
node packages/cli/dist/shardis-cli.js --url ws://localhost:7001/ws GET hello
The CLI follows MOVED redirects automatically. To use the compact binary protocol instead of JSON:
node packages/cli/dist/shardis-cli.js --binary --url ws://localhost:7001/ws SET hello world
pnpm --filter @shardis/dashboard dev
Open http://localhost:3000. With the Compose cluster running, the dashboard shows topology, node health, replication state, events, and an in-browser console.
| Area | Included behavior |
|---|---|
| Storage | In-memory keys, TTLs, active and lazy expiry, and LRU eviction |
| Persistence | AOF writes before acknowledgement, snapshots, compaction, and recovery replay |
| Routing | 16,384 CRC16 hash slots, hash tags, MOVED redirects, and runtime slot ownership |
| Resharding | Slot-by-slot MIGRATING / IMPORTING handoff with ASK redirects and resume support |
| Replication | Leader streaming, follower acknowledgements, lag visibility, full resync, and membership relay |
| Failover | Deterministic promotion by default; opt-in Raft-lite elections and majority commit tracking |
| Messaging | Local sharded pub/sub and optional cluster-scoped publish relay |
| Protocols | JSON over WebSocket by default, plus an opt-in compact binary protocol |
| Observability | /healthz, /metrics, /topology, structured logs, CLI, and dashboard |
Shardis is designed to be observed under failure. Kill the leader of shard A, then inspect its follower:
docker compose kill -s SIGKILL node-a1
curl http://localhost:7002/healthz
docker compose up -d node-a1
In deterministic mode, the lowest live follower id promotes. The returning node reconnects and completes a full resynchronization. The test suite also covers follower outages, stale redirects, dynamic joins, graceful shutdown, and crash recovery.
Client requests are WebSocket messages using commands such as GET, SET, DEL, EXPIRE, TTL, SUBSCRIBE, UNSUBSCRIBE, and PUBLISH.
| Endpoint | Purpose |
|---|---|
GET /healthz | Node identity, shard, role, and uptime |
GET /metrics | Operation, eviction, connection, and replication-lag metrics |
GET /topology | The topology loaded by that node; used for dashboard bootstrap |
WS /ws | WebSocket client and peer protocol endpoint |
By default, pub/sub is sharded: publishes reach subscribers connected to the receiving node. Use scope: "cluster" (CLI: PUBLISH channel message --cluster) to relay an event once to other shards.
All node configuration is environment-driven. Copy .env.example when running a node outside Compose.
| Variable | Description | Default |
|---|---|---|
NODE_ID | Stable node identifier | node-a1 |
ROLE | Boot role hint | leader |
SHARD_ID | Node's shard | shard-a |
CLUSTER_CONFIG_PATH | Static topology file | ./cluster.config.local.json |
PORT | HTTP and WebSocket port | 7000 |
DATA_DIR | AOF and snapshot directory | ./data/<NODE_ID> |
FAILOVER_MODE | deterministic or raft | deterministic |
JOIN_URL / NODE_URL | Dynamic-follower join configuration | unset / derived |
PUBLIC_DEMO / DEMO_WRITE_KEY | Demo write protection | false / unset |
CLUSTER_SECRET | Shared peer authentication secret | unset |
MAX_CONNECTIONS_PER_IP | Concurrent connection cap per source IP | 20 |
Benchmarks are recorded with a timestamp and commit hash in docs/benchmarks.md. Current local measurements include:
| Scenario | Result |
|---|---|
| Throughput | 2,260 ops/sec with 10 clients over 5 seconds |
| Scaling sweep | 18,123 ops/sec peak at 5 clients in a short single-node sweep |
| Failover recovery | 2,846 ms total with a 3,000 ms heartbeat timeout |
| Replication lag | 4.5 ms average; 7 ms p95 across 50 samples |
| Range recompute | ~50% of keys move when changing 3 shards to 4 |
These are local, controlled-environment measurements—not capacity guarantees. Reproduce them with the benchmark package after building the node:
pnpm --filter @shardis/benchmarks bench:<name>
Shardis is not intended to be exposed directly to the public internet.
ws:// internally. Terminate TLS at a reverse proxy or managed platform and expose only wss:// to clients.PUBLIC_DEMO=true can require DEMO_WRITE_KEY for mutating operations; this is a demo safeguard, not user authentication or tenant isolation.CLUSTER_SECRET.Please review SECURITY.md before reporting a vulnerability or deploying an internet-facing instance.
The reduced two-node Render demo is intentionally a preview environment, not an always-on service. Free Render web services sleep after 15 minutes without traffic and can take roughly a minute to wake. The dashboard retries nodes automatically and displays a waking state during that interval. We deliberately do not run synthetic keep-alive traffic: keeping two services active all month would exceed a free workspace's shared instance-hour budget. Use local Docker Compose for the full, durable six-node cluster.
packages/
node/ Store engine, persistence, protocol, replication, routing
cli/ Redirect-aware WebSocket client
dashboard/ Next.js cluster dashboard
benchmarks/ Throughput, failover, lag, and reshard benchmark runners
docs/
architecture.md System design and decisions
benchmarks.md Dated benchmark history
deployment.md Render and Vercel deployment guide
ci-cd.md CI/CD and release operations
pnpm build
pnpm test
pnpm lint
pnpm audit --audit-level moderate
GitHub Actions builds and tests every package, audits dependencies, runs the real-process node integration suite, and starts the complete Compose topology for an end-to-end CLI write/read smoke test. Additional workflows run CodeQL, Gitleaks, scheduled chaos checks, benchmarks, and container-image releases.