A replica connects to a master, asks for a full sync, then receives every subsequent write as it happens. The replica is read-only.
# Terminal 1: master
make 08-replication
# Terminal 2: replica
uv run python 08-replication/server.py --replica-of 127.0.0.1:6380 --port 6381# Terminal 3: writes go to master
redis-cli -p 6380 SET foo bar
redis-cli -p 6380 SET counter 5
# Reads work on either node
redis-cli -p 6380 GET foo # "bar"
redis-cli -p 6381 GET foo # "bar" — replicated
# Writes refused on replica
redis-cli -p 6381 SET x y # (error) READONLY This is a replica node- Replica opens a TCP connection to the master
- Replica sends
*1\r\n$4\r\nSYNC\r\n - Master walks its STORE and sends one
SET key valueper key - Master keeps the socket alive in
REPLICA_SOCKETS - Every successful write on the master is fanned out to every replica socket
- Replica's read loop applies each incoming command to its local store
That's all of it. Real Redis adds checksums, partial resync, replication backlogs, but the core mechanism is this.
REPLICA_SOCKETS: list[socket]— sockets the master streams writes toIS_REPLICAflag — refuse writes from clients on a replica_in_replication_applythread-local — distinguishes "client write" (refuse) from "replicated write" (apply)
Step 9 swaps threads for an event loop. The same data structures stay. The concurrency model becomes single-threaded non-blocking, like real Redis.