Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hyperion

Hyperion is a replicated key-value store built to explore distributed systems and Raft. It is a learning project, not a production database: it has one Raft group, no sharding, no authentication, and no TLS.

How it works

Every hyprd process is a complete node that participates in Raft consensus and stores data in BadgerDB, exposing HTTP and gRPC APIs. Clients use hyprctl to send requests through either API, and both feed into the same store. Raft elects one node as the leader and replicates each write through a majority of the cluster before applying it to BadgerDB. BoltDB keeps the Raft state, while BadgerDB holds the user-visible key-value data.

                         Raft TCP :9001
HTTP :8080 ─┐          ┌────────────────┐
            ├─> Store ─> replicated log ─> BadgerDB
gRPC :8081 ─┘          └────────────────┘

Clients (Users) can connect to any node. If a request reaches a follower, its HTTP handler acts as a reverse proxy to the current leader, while its gRPC handler calls the same RPC on the leader. The leader then serves the linearizable read or coordinates the write through Raft.

                          forwarded request
Client ──────> Follower ──────────────────> Leader ──────> Store ──────> Raft
               │                            │
               ├─ HTTP reverse proxy        ├─ HTTP handler
               └─ gRPC forwarding           └─ gRPC handler

Data is stored under ~/.hyperion/data/<node-id>.

For more background information, read the Raft notes and the distributed KV overview.

Run with Docker Compose

Start a three-node cluster:

make docker-run

Compose gives each node its own container and data volume, bootstraps node 1, and joins nodes 2 and 3. The nodes publish HTTP on ports 8080, 8082, and 8084; gRPC on 8081, 8083, and 8085; and Raft on 9001, 9002, and 9003.

docker compose exec node-1 hyprctl set greeting hello
docker compose exec node-1 hyprctl get greeting

The image includes both hyprd and hyprctl. You can also run make build and use the local hyprctl in the bin/ directory against the Docker cluster.

Use make docker-config to validate the Compose configuration, and make docker-status or make docker-logs to inspect the cluster. Run make docker-stop to preserve its data or make docker-clean to delete it.

Run Locally

Build and start one node:

make build
hyprd --bootstrap

Use hyprctl from another terminal:

hyprctl set greeting hello
hyprctl get greeting
hyprctl get
hyprctl del greeting

HTTP on 127.0.0.1:8080 is the default. To use gRPC instead, pass --protocol grpc --addr 127.0.0.1:8081.

Run a local three-node cluster

Start each node in a separate terminal:

hyprd --node-id n1 --node-addr 127.0.0.1:9001 \
  --srv-port :8080 --grpc-addr :8081 --bootstrap

hyprd --node-id n2 --node-addr 127.0.0.1:9002 \
  --srv-port :8082 --grpc-addr :8083

hyprd --node-id n3 --node-addr 127.0.0.1:9003 \
  --srv-port :8084 --grpc-addr :8085

Then join the followers through node 1:

hyprctl join --node-id n2 --node-addr 127.0.0.1:9002 \
  --http-addr 127.0.0.1:8082 --grpc-addr 127.0.0.1:8083
hyprctl join --node-id n3 --node-addr 127.0.0.1:9003 \
  --http-addr 127.0.0.1:8084 --grpc-addr 127.0.0.1:8085

The advertised client addresses are optional when every node uses the same internal HTTP and gRPC ports (as in Docker Compose). Specify them when several nodes share a host and therefore listen on different ports.

Interfaces

The HTTP API is under /hypr:

Method Path Operation
PUT /hypr/kv/{key} set a value from the raw request body
GET /hypr/kv/{key} get a value
DELETE /hypr/kv/{key} delete a value (idempotent)
GET /hypr/kv/ list all values
POST /hypr/raft/join add a Raft voter

The gRPC contract is in proto/hyperion.proto. The server supports gRPC health checking and reflection.

Development

make check    # generate, vet, test, and build
make generate # regenerate protobuf bindings
make clean    # remove local binaries

Roadmap

  • Create file structure
  • Get working DB and spin HTTP server with hyprd
  • Implement Raft for consensus between nodes (single node for now)
    • Add support for clustering and replication
    • Support leader-only linearizable reads and writes
    • Allow requests through any node by forwarding them to the leader
  • Implement hyprctl CLI to interact with running hyprd nodes
  • Add gRPC API support
  • Add Docker support
  • Add Kubernetes support
  • Build a chaos test harness for Docker and Kubernetes
    • Network partitions
    • Leader churn
    • kill -9 crashes
    • Concurrent multi-client writes
  • Add documentations and useful things I learnt (upkeep as much as possible)

About

a distributed, reliable key-value database using Raft consensus algorithm

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages