A lightweight distributed key-value store built on Raft consensus
Features • Architecture • Quick Start • API • Configuration
RaftKV is a distributed key-value store that combines a high-performance C++ storage engine with the reliability of the Raft consensus algorithm. The system uses a sidecar architecture where cluster coordination and replication are handled by a Go-based component using HashiCorp Raft, ensuring strong consistency with minimal coupling between components.
- High Performance — C++ storage engine with in-memory operations and persistent storage
- Strong Consistency — Raft consensus ensures all nodes agree on the order of operations
- Efficient Serialization — MsgPack binary protocol for minimal overhead
- Docker Ready — Multi-stage Docker build with Docker Compose for easy cluster deployment
- gRPC Communication — Fast inter-service communication between components
- Fault Tolerant — Automatic leader election and cluster recovery
- HTTP API — Simple REST-like interface for client applications
┌─────────────────────────────────────────────────────────────────┐
│ RaftKV Node │
├─────────────────────────────────┬───────────────────────────────┤
│ C++ Storage Engine │ Go Raft Sidecar │
│ │ │
│ ┌─────────────────────────┐ │ ┌───────────────────────┐ │
│ │ HTTP Server │ │ │ HashiCorp Raft │ │
│ │ (Port 8080) │ │ │ (Port 8088) │ │
│ └──────────┬──────────────┘ │ └───────────┬───────────┘ │
│ │ │ │ │
│ ┌──────────▼──────────────┐ │ ┌───────────▼───────────┐ │
│ │ State Machine │◄───┼────│ RaftNode gRPC │ │
│ │ (gRPC :50051) │ │ │ (Port 50052) │ │
│ └──────────┬──────────────┘ │ └───────────────────────┘ │
│ │ │ │
│ ┌──────────▼──────────────┐ │ ┌───────────────────────┐ │
│ │ Persistent Storage │ │ │ Management API │ │
│ │ (kv.db) │ │ │ (Port 6000) │ │
│ └─────────────────────────┘ │ └───────────────────────┘ │
└─────────────────────────────────┴───────────────────────────────┘
| Component | Language | Description |
|---|---|---|
| Storage Engine | C++ | Handles HTTP requests, manages the key-value store, and persists data to disk |
| Raft Sidecar | Go | Manages cluster membership, leader election, and log replication using HashiCorp Raft |
| Protocol Buffers | Protobuf | Defines the gRPC service contracts between components |
- Client Request → HTTP POST to
/insert-valwith MsgPack payload - Proposal → C++ engine forwards to Go sidecar via gRPC
- Consensus → Leader replicates log entry to followers via Raft
- Apply → Once committed, sidecar calls back to C++ state machine
- Persist → C++ engine updates in-memory store and writes to disk
- Docker and Docker Compose
- (For local development) Go 1.24+, CMake, gRPC/Protobuf libraries
# Build the Docker image
docker build -t raftkv:latest .
# Start a 3-node cluster
docker-compose up -d
# View logs
docker-compose logs -f# Install Python dependencies
pip install requests msgpack
# Run the test client
python test_client.pyOr use curl directly:
# Write a value (using Python for MsgPack encoding)
python3 -c "
import requests, msgpack
data = msgpack.packb({'op': 'SET', 'key': 'hello', 'value': 'world'})
print(requests.post('http://localhost:8080/insert-val', data=data,
headers={'Content-Type': 'application/msgpack'}).text)
"
# Read a value
curl "http://localhost:8080/get-val?key=hello"POST /insert-val
Content-Type: application/msgpackRequest Body (MsgPack encoded):
{
"op": "SET",
"key": "your_key",
"value": "your_value"
}Response: ok on success, error on failure
GET /get-val?key=<key>Response: The value associated with the key, or Key Not Found
POST /insert-val
Content-Type: application/msgpackRequest Body (MsgPack encoded):
{
"op": "DELETE",
"key": "your_key",
"value": ""
}GET http://<leader>:6000/join?peerID=<node_id>&peerAddress=<raft_address>Adds a new node to the Raft cluster.
| Variable | Description | Default |
|---|---|---|
NODE_ID |
Unique identifier for this node | node1 |
BOOTSTRAP |
Set to true for the initial leader |
false |
JOIN_ADDR |
Leader's management address for joining | - |
| Port | Service | Description |
|---|---|---|
| 8080 | HTTP API | Client-facing REST API |
| 8088 | Raft | Raft consensus protocol |
| 6000 | Management | Cluster join/leave operations |
| 50051 | gRPC | C++ StateMachine service |
| 50052 | gRPC | Go RaftNode service |
RaftKV/
├── cpp-app/ # C++ Storage Engine
│ ├── main.cpp # HTTP server, gRPC service, KV store
│ ├── CMakeLists.txt # Build configuration
│ └── pb/ # Generated Protobuf files
├── go-sidecar/ # Go Raft Sidecar
│ ├── main.go # Raft setup, gRPC service
│ ├── go.mod # Go module dependencies
│ └── pb/ # Generated Protobuf files
├── proto/
│ └── consensus.proto # Service definitions
├── docker-compose.yml # Multi-node cluster setup
├── Dockerfile # Multi-stage build
├── entrypoint.sh # Container startup script
└── test_client.py # Python test client
cd cpp-app
mkdir build && cd build
cmake ..
make -j$(nproc)Dependencies:
- CMake 3.10+
- gRPC and Protocol Buffers
- MsgPack for C++ (
libmsgpack-dev)
cd go-sidecar
go build -o sidecar .Dependencies:
- Go 1.24+
- HashiCorp Raft
- gRPC for Go
RaftKV uses the Raft algorithm to maintain consistency across nodes:
- Leader Election — One node is elected leader; it handles all write requests
- Log Replication — The leader appends entries to its log and replicates to followers
- Commit — Once a majority acknowledge, the entry is committed
- Apply — Committed entries are applied to each node's state machine
The sidecar architecture decouples the storage logic from consensus:
- C++ handles performance-critical storage operations
- Go leverages the mature HashiCorp Raft implementation
- gRPC provides efficient communication between them
This design allows each component to be optimized independently while maintaining clear interfaces.
Contributions are welcome! Please feel free to submit issues and pull requests.
This project is open source and available under the MIT License.