Log Replication
// TODO
POST /raft/append-entries
Section titled “POST /raft/append-entries”Extends the heartbeat RPC from leader election to carry actual log entries.
POST /raft/append-entries
{ "term": 3, "leader-id": "10.0.42.101:8080", "prev-log-index": 2, "prev-log-term": 2, "entries": [ { "index": 3, "term": 3, "command": "PUT foo bar" }, { "index": 4, "term": 3, "command": "DELETE baz" } ], "leader-commit": 2}
----
200{ "term": 3, "success": true}prev-log-index/prev-log-term: index and term of the entry immediately preceding the new ones; follower rejects if it doesn’t matchentries: one or more log entries to append; empty for heartbeats as beforeleader-commit: leader’s current commit index; follower advances its own commit index tomin(leader-commit, index of last new entry)success:falseif the follower’s log didn’t matchprev-log-index/prev-log-term; leader will decrementnextIndexand retry
GET /log
Section titled “GET /log”Returns current log entries (after the snapshot point, if any), commit index, and last applied index.
GET /log
----
200{ "entries": [ { "index": 1, "term": 1, "command": "PUT foo bar" }, { "index": 2, "term": 1, "command": "DELETE foo" }, { "index": 3, "term": 2, "command": "PUT baz qux" } ], "commit-index": 3, "last-applied": 3}Rough Notes
Section titled “Rough Notes”External contract
Section titled “External contract”- PUT/DELETE return 200 only after the entry is committed to a majority
- GET returns only committed, applied state
- GET /log returns entries (from snapshot point onwards), commit-index, and last-applied
- Redirect contract from leader election unchanged - following a redirect now has real semantics
Implementation
Section titled “Implementation”- Raft log replaces the WAL from stage 3
- Leader appends client operations to log, replicates to followers via AppendEntries RPC
- Entry committed when replicated to majority - leader advances commit index
- Followers apply committed entries to state machine (KV store)
- Log consistency checks (prevLogIndex, prevLogTerm) on every AppendEntries
- Truncate conflicting uncommitted entries on followers
- nextIndex and matchIndex tracking per follower
- Fsync log entries before responding to client
- Happy path only - no crashes/failures yet
Testing
Section titled “Testing”- Linearizability verified with porcupine
- Requires history recording in the test framework (track operation start/end times and observed values across concurrent requests)
Resources
Section titled “Resources”- The Raft Consensus Algorithm
- Distributed Systems 6.2: Raft by Martin Kleppmann
- Students’ Guide to Raft by Jon Gjengset
- Database Internals Chapter 14: Consensus by Alex Petrov
- Designing Data-Intensive Applications Chapter 5: Replication by Martin Kleppmann