redis/redis
Cluster
Active contributors: antirez, Oran Agra, Binbin, Wen Hui.
Purpose
Cluster mode shards keys across multiple redis-server processes. The keyspace is divided into 16384 hash slots. Each slot is owned by exactly one master at a time; each master has zero or more replicas. Clients route commands by computing CRC16(key) % 16384 and looking up the slot's owner; if they get it wrong, the master returns a MOVED redirect telling them where the slot lives.
Cluster mode is opt-in (cluster-enabled yes). It is not a separate binary — redis-server simply uses different code paths when cluster mode is on.
Source layout
| File | Role |
|---|---|
src/cluster.c |
The shared cluster API used by the rest of the server: slot computation, command routing, CLUSTER command dispatch. |
src/cluster.h |
Public types and prototypes. |
src/cluster_legacy.c |
The original cluster transport: gossip, failover, slot migration, keyspace fan-out for cross-slot operations. ~6,500 lines. |
src/cluster_legacy.h |
Legacy cluster types. |
src/cluster_asm.c |
Auto Slot Migration: an automated rebalancer. ~4,500 lines. |
src/cluster_asm.h |
ASM types. |
src/cluster_slot_stats.c |
Per-slot statistics, used by CLUSTER COUNTKEYSINSLOT, CLUSTER SLOT-STATS. |
src/crc16.c, src/crc16_slottable.h |
Slot hash function and the lookup table for hash tags. |
Slots and hash tags
CRC16(key) % 16384 decides the slot. With hash tags, the routing key is just the substring inside the first {...} pair. So user:{42}:profile and user:{42}:posts both map to the same slot, allowing multi-key operations.
CLUSTER KEYSLOT <key> returns the computed slot for diagnostics.
Routing in processCommand
Every command goes through a slot check before dispatch:
- Iterate the command's declared key positions (from the JSON spec via
commands.def). - Compute the slot for each.
- If they all land in the same slot owned by this node, proceed.
- If a slot is owned by another node →
-MOVED <slot> <ip>:<port>. - If a slot is migrating out of this node and the key isn't here →
-ASK <slot> <ip>:<port>. - If
CMD_NO_MULTIand there's an openMULTI→ reject. - If multiple slots are touched →
-CROSSSLOT.
The implementation is getNodeByQuery in src/cluster.c.
Cluster bus
Each cluster node opens a second TCP listener on port + 10000. Cluster nodes connect to each other on the bus and exchange:
- PING / PONG — heartbeat with gossip section.
- MEET — initial introduction (
CLUSTER MEET <ip> <port>). - FAIL — broadcast a node failure.
- PUBLISH / MPUBLISH — sharded pubsub propagation.
- UPDATE — slot ownership changes.
- PUBLISHSHARD — shard-local pubsub.
- MFSTART — manual failover signal.
- PSYNC commands during failover.
The bus uses a binary header (clusterMsg in src/cluster_legacy.h) followed by a type-dependent body. Implementation: clusterReadHandler, clusterProcessPacket in src/cluster_legacy.c.
Gossip
Every PING includes a "gossip section" — a small random sample of other known nodes, with their IPs, ports, flags, and last ping/pong timestamps. Receivers update their own view. With ~10 PINGs per second per node and a few gossip entries per PING, a cluster reaches eventual consistency on membership in ~tens of seconds.
When a node hasn't heard from a peer for cluster-node-timeout ms it marks the peer PFAIL (probable fail). When a quorum of masters report PFAIL for the same peer, it is escalated to FAIL and broadcast.
Automatic failover
sequenceDiagram
participant R as Replica of failed master
participant Others as Other masters
participant New as Promoted node
Note over R: Detect master FAIL
R->>R: Wait random delay (anti-thundering-herd)
R->>Others: FAILOVER_AUTH_REQUEST
Others->>R: FAILOVER_AUTH_ACK (if epoch is highest)
Note over R: Got majority
R->>R: Promote: take ownership of slots
R->>Others: PONG with new flagsThe protocol bumps the cluster epoch and the master's config epoch — these are the version numbers that prevent split-brain. The implementation is clusterHandleSlaveFailover and clusterRequestFailoverAuth in src/cluster_legacy.c.
CLUSTER FAILOVER [FORCE|TAKEOVER] triggers a manual failover.
Slot migration
The legacy slot-migration protocol uses two commands:
CLUSTER SETSLOT <slot> MIGRATING <node>— on the source.CLUSTER SETSLOT <slot> IMPORTING <node>— on the destination.- Then
MIGRATE <host> <port> <key> 0 <timeout>per key from the source. - Finally
CLUSTER SETSLOT <slot> NODE <node>on both nodes.
While in MIGRATING/IMPORTING:
- Reads on the source for keys that still exist work normally.
- Reads on the source for keys that have already migrated →
-ASK. - Reads on the destination only succeed if preceded by an
ASKINGcommand.
redis-cli --cluster reshard automates this dance.
Auto Slot Migration
src/cluster_asm.c adds an automated rebalancer. The "ASM" name is "Auto Slot Migration", not "assembly". Goals:
- Move slots automatically when load is uneven.
- Rebalance after a node is added or removed.
- Coordinate so that only one ASM operation runs at a time per cluster.
The full design is documented inline in src/cluster_asm.c at the top of the file. The user-facing surface is a set of CLUSTER-namespace commands (CLUSTER MIGRATION ..., CLUSTER SYNCSLOTS ...).
CLUSTER commands
Selected subcommands and their files:
| Command | Description | Implementation file |
|---|---|---|
CLUSTER INFO |
Cluster state and node count. | cluster_legacy.c |
CLUSTER NODES |
Full node table. | cluster_legacy.c |
CLUSTER MYID |
This node's id. | cluster_legacy.c |
CLUSTER MEET <ip> <port> |
Bootstrap a connection. | cluster_legacy.c |
CLUSTER ADDSLOTS / DELSLOTS / ADDSLOTSRANGE / DELSLOTSRANGE |
Manual slot ownership. | cluster_legacy.c |
CLUSTER SETSLOT |
The slot-migration state machine. | cluster_legacy.c |
CLUSTER FORGET <node> |
Remove a node from the table. | cluster_legacy.c |
CLUSTER REPLICATE <master> |
Become a replica of <master>. |
cluster_legacy.c |
CLUSTER LINKS |
Per-node bus link state. | cluster_legacy.c |
CLUSTER COUNT-FAILURE-REPORTS |
How many masters flagged a peer. | cluster_legacy.c |
CLUSTER SLOT-STATS |
Per-slot hit/miss/cpu accounting. | cluster_slot_stats.c |
CLUSTER COUNTKEYSINSLOT / GETKEYSINSLOT |
Slot inspection. | cluster_slot_stats.c |
CLUSTER MIGRATION ... |
The ASM API. | cluster_asm.c |
CLUSTER SYNCSLOTS ... |
Online slot resync. | cluster_asm.c |
CLUSTER FAILOVER |
Trigger manual failover. | cluster_legacy.c |
CLUSTER RESET |
Wipe runtime cluster state. | cluster_legacy.c |
CLUSTER SHARDS |
Shard-grouped view. | cluster_legacy.c |
Per-DB consequences
Cluster mode forces dbnum 1. Multi-DB (SELECT 0..15) does not exist in cluster mode because there is no good way to map slots across DBs.
Limits
- Recommended max 1000 master nodes (
cluster-announce-ipaccounting and gossip get expensive past that). - 16384 slots is fixed and intentional (
crc16_slottable.his precomputed for that count). - Cross-slot transactions and Lua scripts are forbidden — the
CMD_KEY_OPTIONScheck rejects them.
Related pages
- Replication
- redis-cli —
--clustersubcommand. - Pub/Sub & tracking — sharded Pub/Sub.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.