Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

README.md

08: Replication

A replica connects to a master, asks for a full sync, then receives every subsequent write as it happens. The replica is read-only.

Run it

# 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

The wire dance

  1. Replica opens a TCP connection to the master
  2. Replica sends *1\r\n$4\r\nSYNC\r\n
  3. Master walks its STORE and sends one SET key value per key
  4. Master keeps the socket alive in REPLICA_SOCKETS
  5. Every successful write on the master is fanned out to every replica socket
  6. 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.

What's new

  • REPLICA_SOCKETS: list[socket] — sockets the master streams writes to
  • IS_REPLICA flag — refuse writes from clients on a replica
  • _in_replication_apply thread-local — distinguishes "client write" (refuse) from "replicated write" (apply)

What's next

Step 9 swaps threads for an event loop. The same data structures stay. The concurrency model becomes single-threaded non-blocking, like real Redis.