mökv is a distributed, in-memory key-value store built with Raft for consensus, Serf for discovery, and gRPC for communication.
Built it following the book Distributed Services with Go by Travis Jeffery.
- Distributed & Fault-Tolerant: Data replicated across multiple nodes using Raft consensus
- In-Memory Storage: Fast read/write operations with persistent snapshots
- Service Discovery: Automatic node discovery and membership via Serf
- Smart Load Balancing: Client-side routing directs writes to leader, reads to followers
makeThis will:
- Create a kind cluster
- Build the Docker image
- Load it into kind
- Deploy with Helm
- Wait for all pods to be ready
Then test it:
kubectl port-forward pod/mokv-0 9800:8400
# In another terminal:
go run cmd/get_servers.go -addr localhost:9800Customize via deploy/mokv/values.yaml or override during installation:
helm install mokv deploy/mokv --set replicas=5 --set storage=2GiDefault values:
replicas: 3 # Number of nodes
storage: 1Gi # Persistent volume size per node
rpcPort: 8400 # gRPC port
serfPort: 8401 # Serf discovery portmökv exposes a gRPC API defined in api/kv.proto:
service KV {
rpc Get(GetRequest) returns (GetResponse);
rpc Set(SetRequest) returns (SetResponse);
rpc Delete(DeleteRequest) returns (DeleteResponse);
rpc List(google.protobuf.Empty) returns (stream GetResponse);
rpc GetServers(google.protobuf.Empty) returns (GetServersResponse);
}Raft Consensus: Ensures strong consistency with leader-based replication. Writes go through the leader and are replicated to followers.
Serf Discovery: Nodes automatically discover each other via gossip protocol. When a node joins via Serf, it's added as a Raft voter.
Client-Side Load Balancing: Custom gRPC resolver and picker route:
- Writes (
Set,Delete) → Leader - Reads (
Get,List) → Followers (load balanced)
Kubernetes Components:
- StatefulSet: Stable network identities (mokv-0, mokv-1, mokv-2)
- Headless Service: Direct pod-to-pod communication via FQDNs
- PersistentVolumeClaims: Durable storage for Raft logs and snapshots
- Init Container: Auto-configures each pod (bootstrap vs join)
Update deployment:
make docker-build
make kind-load
kubectl rollout restart statefulset mokvScale the cluster:
helm upgrade mokv deploy/mokv --set replicas=5Uninstall:
make cleanFor local testing without Kubernetes, see example/start_nodes.sh.