Ruvio.

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

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.

FieldMeaning
replication_roleoff, primary, or replica
wal_last_sequenceLast WAL record this process appended
wal_durable_sequenceLast WAL record this process synced to disk
replication_replicasReplica sockets connected to this primary. 0 on a replica
replication_replica_sequenceOldest sequence this primary has written to a connected replica socket
replication_send_lagwal_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.

  1. Stop clients from writing to the primary. A replica answers READONLY to a write.
  2. On each primary shard, wait until wal_last_sequence equals wal_durable_sequence.
  3. On each replica shard, wait until wal_durable_sequence equals that same number.
  4. 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.
  5. Stop the replica. Keep its data directory.
  6. Start that directory as the writer. One process, with no further replicas, uses role = "off". A new primary that should accept replicas sets role = "primary" and its own listen. Keep everysec or always, and the same shards.
  7. Point clients at the new RESP address.
  8. 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.