Skip to content

Clustering

A FrogDB cluster shards the keyspace across nodes using 16384 hash slots. Cluster metadata — membership, slot ownership, failover decisions, and config epochs — is coordinated by Raft consensus, while the data itself is replicated over the PSYNC data plane. This page covers the architecture split, slot routing, bootstrapping, topology management, the admin API, and failure modes. For the data-sync mechanics beneath the cluster, see Replication.

FrogDB separates the control plane from the data plane. Raft (built on the openraft consensus library) is the single source of truth for cluster metadata; it is never on the request path for key reads and writes.

PlaneMechanismResponsibilities
Control (metadata)Raft consensusCluster membership, slot-ownership changes, failover decisions, config epochs.
DataPSYNC / WAL streamingKey-value replication, read/write execution, slot-data migration.

This is the same division of labor as Redis Cluster’s config-epoch metadata versus its data replication, but the metadata is agreed by Raft rather than gossip, which makes topology changes explicit and linearizable.

Every key maps to one of 16384 hash slots using the Redis-compatible CRC16 (XMODEM) hash:

slot = CRC16(key) % 16384

Slots are owned by primary nodes. Internally, each node also routes keys to a thread-per-core shard, and that routing is derived from the same hash:

internal_shard = CRC16(key) % 16384 % num_shards

Because both levels start from CRC16(key), a key’s cluster slot and its internal shard are computed from the same value. (CRC16 is used for all key routing; the xxhash64 function appears only inside probabilistic data structures, never in slot or shard assignment.)

A key containing {tag} hashes on the tag content only, so related keys colocate on the same slot — and, because both routing levels share the hash, on the same internal shard:

Terminal window
# Both keys hash on "user:123" and land in the same slot
SET {user:123}:profile "..."
SET {user:123}:settings "..."
# Guaranteed same-slot, so this multi-key op is allowed
MGET {user:123}:profile {user:123}:settings

Multi-key operations whose keys span more than one slot are rejected. See Redis compatibility differences for cross-slot behavior.

Primary — owns one or more slot ranges, accepts writes for those slots, streams changes to its replicas, and answers client requests for owned slots (or replies -MOVED to redirect a client to the owning node).

Replica — holds a full copy of its primary’s dataset, serves reads only when the client opts in with READONLY, and is a candidate for promotion during failover.

Cluster mode is off by default. Each node enables it under [cluster], sets a node-id, exposes a cluster-bus-addr for Raft traffic, and lists the initial members in initial-nodes:

[cluster]
enabled = true
node-id = 1
cluster-bus-addr = "10.0.0.1:16379"
initial-nodes = [
"10.0.0.1:16379",
"10.0.0.2:16379",
"10.0.0.3:16379",
]

initial-nodes seeds the member set. The node with the lowest node-id bootstraps the Raft cluster by calling initialize; this step is idempotent, so restarting a bootstrapped node does not re-bootstrap it. On first bootstrap that node auto-assigns all 16384 slots evenly across the initial primaries as contiguous ranges and replicates the assignment to followers through Raft.

Once the nodes are up, verify the cluster with:

Terminal window
redis-cli CLUSTER INFO
redis-cli CLUSTER NODES
redis-cli CLUSTER SHARDS

The [cluster] keys and defaults:

KeyDefaultPurpose
enabledfalseEnable cluster mode.
node-id0This node’s ID (0 auto-generates one).
client-addr""Client-facing address (defaults to the server bind/port).
cluster-bus-addr127.0.0.1:16379Raft/cluster-bus address (conventionally the client port + 10000).
initial-nodes[]Seed member cluster-bus addresses.
data-dir./frogdb-clusterDirectory for Raft logs and snapshots.
election-timeout-ms1000Raft election timeout.
heartbeat-interval-ms250Raft heartbeat interval (must be below the election timeout).
connect-timeout-ms5000Cluster-bus connect timeout.
request-timeout-ms10000Cluster-bus RPC timeout.
auto-failoverfalseLet the Raft leader promote a replica automatically.
fail-threshold5Consecutive failures before a node is marked failed.
self-fence-on-quorum-losstrueReject writes when this node cannot form a quorum.
replica-priority100Promotion preference during auto-failover (lower is preferred; 0 never promotes).

See the Configuration reference for the generated, authoritative list.

CLUSTER inspection subcommands are served locally from the node’s view of the Raft-replicated state. Topology-mutating subcommands are routed through Raft so the change is agreed and applied consistently across the cluster.

Local inspectionRaft-routed mutation
INFO, NODES, MYID, SLOTS, SHARDS, KEYSLOT, COUNTKEYSINSLOT, GETKEYSINSLOT, HELPMEET, FORGET, ADDSLOTS, DELSLOTS, SETSLOT, REPLICATE, FAILOVER, RESET, SAVECONFIG, SET-CONFIG-EPOCH

The HTTP observability server (default port 9090) exposes read-only cluster and node administration endpoints. When [http] token is set, requests to the protected /admin/* and /debug/* paths must carry an Authorization: Bearer <token> header.

EndpointMethodNotes
/admin/healthGETLiveness and cluster-enabled state.
/admin/clusterGETCluster state snapshot (read-only — it does not accept a topology push).
/admin/roleGETThis node’s role.
/admin/nodesGETKnown nodes.
/admin/upgrade-statusGETRolling-upgrade status.
/admin/shutdownPOSTTrigger a graceful shutdown.
/admin/transfer-leaderPOSTNot implemented — returns an error (the current openraft version has no leadership-transfer API).

A separate RESP-protocol admin listener can be enabled under [admin] (default port 6382, bind 127.0.0.1, disabled by default) for administrative commands over the Redis protocol.

[admin]
enabled = true
bind = "127.0.0.1"
port = 6382

Secure the admin surfaces with network isolation and, for the HTTP endpoints, an [http] token. See Security for TLS and network-boundary guidance.

ScenarioBehavior
Node failureWith auto-failover = true, the Raft leader promotes a replica after fail-threshold consecutive failures, choosing among candidates by replica-priority. With the default auto-failover = false, promotion is manual via CLUSTER FAILOVER.
Quorum lossWith self-fence-on-quorum-loss = true (default), a node that cannot form a quorum rejects writes with CLUSTERDOWN while continuing to serve reads, preventing split-brain divergence.
Raft leader lossA standard openraft election runs, governed by election-timeout-ms and heartbeat-interval-ms. Explicit leadership transfer is not implemented.

Inspect cluster health and membership with CLUSTER INFO, CLUSTER NODES, and CLUSTER SHARDS; CLUSTER INFO reports the cluster state (ok/fail), the number of assigned slots, known nodes, and the config epoch. Exported Prometheus metrics are listed in the Metrics reference.

  • Replication — the PSYNC data plane and write quorum.
  • Deployment — packaging and the Kubernetes operator status.
  • Security — admin-API authentication and TLS.