A distributed consensus algorithm implementation in Golang, based on the Raft paper. This project simulates a fault-tolerant cluster where multiple nodes work together to maintain a consistent, replicated log using RPC (Remote Procedure Calls).
-
Leader Election: Automated transition between Follower, Candidate, and Leader states using randomized election timeouts (
$150ms$ -$300ms$ ). -
Log Replication: Leaders replicate log entries to followers via AppendEntries RPCs and maintain consistency across the cluster.
-
Persistence: Critical state (CurrentTerm, VotedFor, and Log) is persisted to local .dat files using Go's encoding/gob to survive node crashes.
-
Interactive CLI: Real-time interaction with specific nodes to submit commands, check status, and inspect logs.
-
Safety: Implements the "up-to-date" log check during elections to ensure only nodes with the most recent data can become leaders.
-
main.go: Entry point providing a CLI interface to interact with a Raft node.
-
raft/raft.go: The core consensus engine (Timer logic, RPC handlers, State transitions).
Clone the repository:
git clone https://github.com/akshatsrivastava11/raft-consensus-sim
cd raft-consensus-simTo simulate a cluster, you need to open multiple terminal windows and start each node individually. By default, the config expects nodes on ports 5000, 5001, and 5002.
Terminal 1 (Node 0):
go run main.go 0Terminal 2 (Node 1):
go run main.go 1Terminal 3 (Node 2):
go run main.go 2Once a node is running, you can use the following commands:
-
status: Displays current state (Leader/Follower), Term, and Commit Index.
-
put : Submits a command to the node. (Note: Only the Leader can accept commands).
-
log: Dumps the current log entries and identifies which are committed.
-
quit: Safely exit the node.
-
Follower: Resets election timer on receiving valid heartbeats from a Leader or granting a vote to a Candidate.
-
Candidate: Increments term, votes for self, and broadcasts RequestVote.
-
Leader: Sends periodic heartbeats (
$100ms$ interval) and manages the NextIndex and MatchIndex for all peers.
-
Commitment: An entry is considered committed once it is replicated on a majority (
$N/2 + 1$ ) of nodes. -
Log Matching: If a follower detects a conflict in the log, the leader decrements the NextIndex and retries until the logs match.
-
Persistence: Every state change (Term, Vote, or Log Append) triggers persist(), saving the state to raft-state-.dat.
You can test the robustness of the algorithm by:
-
Leader Failure: Kill the terminal of the current Leader. Observe as the remaining nodes time out and elect a new Leader.
-
Network Partition: Close one node, submit several put commands to the leader, then restart the closed node. Observe it catching up via AppendEntries.