A minimal implementation of the Raft consensus algorithm in Rust for learning purposes.
- Leader Election
- Heartbeat mechanism
- Request Vote RPC
- Append Entries RPC
- Log replication
- gRPC network layer
- CLI & Config
- E2E Test script
- HTTP Client API
- Log Snapshot (Optional)
- Persistence (Optional)
src/
├── types.rs # Core types (Term, NodeId, LogIndex, RaftState)
├── rpc.rs # RPC messages (RequestVote, AppendEntries)
├── log.rs # Log entry and storage
├── timer.rs # Election and heartbeat timers
├── event.rs # Event types for the event loop
├── node.rs # RaftNode - core Raft logic
├── raft.rs # RaftRunner - event loop with network calls
├── server.rs # gRPC server (receives RPCs)
├── client.rs # gRPC client (sends RPCs)
├── http.rs # HTTP API server
├── lib.rs # Module exports
└── main.rs # CLI entry point
proto/
└── raft.proto # gRPC service definition
Build the project:
cargo build --releaseRun a 3-node cluster (in separate terminals):
# Terminal 1 - Node 1
./target/release/mini-raft --id 1 --port 50051 --peers "2=[::1]:50052,3=[::1]:50053"
# Terminal 2 - Node 2
./target/release/mini-raft --id 2 --port 50052 --peers "1=[::1]:50051,3=[::1]:50053"
# Terminal 3 - Node 3
./target/release/mini-raft --id 3 --port 50053 --peers "1=[::1]:50051,2=[::1]:50052"| Option | Description |
|---|---|
--id |
Unique node ID |
--port |
Port to listen on (gRPC) |
--peers |
Comma-separated peer list: id=host:port,... |
Each node exposes an HTTP API on port gRPC_port + 1000 (e.g., 50051 -> 51051).
Returns the current node status.
curl http://[::1]:51051/statusResponse:
{
"node_id": 1,
"state": "Leader",
"term": 5,
"commit_index": 3
}Submit a command to the cluster (leader only).
curl -X POST http://[::1]:51051/command \
-H "Content-Type: application/json" \
-d '{"command": "set key value"}'Response (success):
{
"success": true,
"index": 4,
"error": null
}Response (not leader):
{
"success": false,
"index": null,
"error": "not_leader"
}TODO: Future versions will include
leader_hintfield to redirect clients to the current leader.
Returns all log entries.
curl http://[::1]:51051/logResponse:
[
{"index": 1, "term": 1, "command": "set foo bar"},
{"index": 2, "term": 1, "command": "set baz qux"}
]MIT