Replication
Write to the primary. Read from the primary or from a replica you chose. The client picks the socket. Lag has no upper bound.
Model
One primary keeps up to 16 replica streams. Each replica has its own stream and its own sequence. The primary does not wait for an acknowledgement. A slow replica blocks only its own send. A new handshake does not close an existing stream. Past 16, the primary accepts the TCP connection, logs that the limit was reached, and closes it without a handshake reply.
The backlog is the WAL on disk. The shipper sends bytes that have been synced, not merely appended. Shard i uses the base replication port plus i. The replica dials that port. It does not use the RESP port for the replication stream.
Config
[persistence] profile = "everysec" data_dir = "./data" [replication] role = "primary" listen = "127.0.0.1:26379"
[replication] role = "replica" primary = "127.0.0.1:26379"
listen must be a numeric address. primary may be numeric or host:port. memory and snapshot refuse replication at startup: replication requires a WAL-backed durability profile. The replication port range must not overlap RESP or metrics. A replica that receives a write answers READONLY You can't write against a read only replica.
Set the same replication_password on the primary and replica to authenticate the replication stream separately from client requirepass. When empty, the replication secret falls back to requirepass. There is no masterauth command.
A missing WAL prefix
Connected replicas pin compaction, so a live replica is not compacted out from under itself. A replica that was offline can still find that its next WAL record is gone.
If the latest checkpoint covers that replica — its sequence is at least the replica's cursor, not past the durable cursor, and the retained WAL starts at or before the next record — the primary sends the checkpoint, then the WAL tail. The replica replaces its shard and, when present, its hot-key store. Deleted keys disappear. It does not roll backward onto an older checkpoint. If no usable checkpoint exists, the stream stops and the replica's memory stays as it was.
What is copied
- Ordinary key mutations, including a hot-key
SETorDEL, through the shard WAL. - Same-shard
PUBLISHandSPUBLISH, live, not replayed from the WAL. CLIENT TRACKINGinvalidations for a copied write.
While replication is enabled, ACL SETUSER, FUNCTION LOAD, FUNCTION DELETE, SCRIPT LOAD, and SCRIPT FLUSH are refused. They are process-local and are not inside the snapshot.
The tail
The primary appends the WAL and moves on. A replica reads that tail. Up to 16 replicas each keep their own sequence. A full sync installs a checkpoint, then continues the tail. CLUSTER NODES lists every shard as master. PUBLISH stays on the shard that accepted it. The primary you configured is the primary that serves.
Promote by hand
The process does not elect a primary. You stop writers, wait until the replica's disk matches the primary, then start that data directory as the writer. Repeat for every shard. Shard i is the RESP port plus i.
redis-cli -p 6379 INFO includes a # Replication block. Read it on every shard port.
| Field | Meaning |
|---|---|
replication_role | off, primary, or replica |
wal_last_sequence | Last WAL record this process appended |
wal_durable_sequence | Last WAL record this process synced to disk |
replication_replicas | Replica sockets connected to this primary. 0 on a replica |
replication_replica_sequence | Oldest sequence this primary has written to a connected replica socket |
replication_send_lag | wal_durable_sequence minus that oldest send. 0 means the bytes left the primary |
The copy you can serve is the replica's wal_durable_sequence.
- Stop clients from writing to the primary. A replica answers
READONLYto a write. - On each primary shard, wait until
wal_last_sequenceequalswal_durable_sequence. - On each replica shard, wait until
wal_durable_sequenceequals that same number. - If the replica's stream stopped on a missing WAL prefix and no checkpoint covered it, leave that replica down. Its memory is the generation it had when the stream stopped.
- Stop the replica. Keep its data directory.
- Start that directory as the writer. One process, with no further replicas, uses
role = "off". A new primary that should accept replicas setsrole = "primary"and its ownlisten. Keepeverysecoralways, and the sameshards. - Point clients at the new RESP address.
- Leave the old primary stopped. Starting it again beside the new writer forks the history.
REPLICAOF does not exist. Changing role is a restart. A client that must not continue until the copy is on disk sends WAIT replicas milliseconds on that shard. The reply is how many replicas synced wal_last_sequence. The write stays on the primary when the count is short.