Overview
ValKeyper is built as a concurrent TCP server that handles multiple client connections simultaneously. The architecture follows a clean separation of concerns with distinct components for networking, protocol handling, and data storage.Core Components
TCP Server
Handles client connections and request routing
RESP Parser
Parses Redis Serialization Protocol messages
KV Store
In-memory storage with expiry management
RDB Handler
Persistence layer for data snapshots
Server Architecture
The main server is implemented inapp/server.go and follows a simple but effective pattern:
Connection Handling
Each client connection is handled in its own goroutine, enabling concurrent request processing:Connection Structure
TheConnection struct maintains per-connection state:
- Transaction support via MULTI/EXEC/DISCARD commands
- Command queueing for atomic execution
- Stateful operations per client
Store Architecture
TheKVStore struct (app/store/store.go) is the heart of the system:
Key Design Decisions
Concurrent Expiry Handling
Concurrent Expiry Handling
Each key with an expiry time gets its own goroutine that waits on a timer. When the timer fires, the key is deleted. This approach is simple and leverages Go’s lightweight goroutines, though it may not scale to millions of keys with expiries.
Replication Architecture
Replication Architecture
ValKeyper supports master-slave replication:
- Master nodes maintain a list of connected slaves and forward write commands
- Slave nodes connect to a master, perform a handshake, and receive commands
- The
WAITcommand enables waiting for a minimum number of replicas to acknowledge writes
Stream Support
Stream Support
ValKeyper implements Redis Streams with:
- Time-based IDs in the format
timestamp-sequence - Automatic ID generation with
*wildcard - Range queries via
XRANGE - Blocking reads via
XREADwith timeout support - Stream-to-stream notifications using channels
Replication Info
TheInfo struct tracks replication state:
Command Processing Flow
The command processor uses a switch statement with over 20 cases, handling everything from simple commands like PING and ECHO to complex operations like XREAD and MULTI/EXEC transactions.
Concurrency Model
ValKeyper’s concurrency model is based on Go’s goroutines:- One goroutine per connection handles all commands from a single client
- One goroutine per expiring key manages TTL expiration
- Shared state protection relies on Go’s map access semantics (not explicitly mutex-protected)
Initialization Flow
The initialization process includes:- Creating a new
KVStorewith default values (master role, port 6379) - Parsing command-line flags for configuration
- Loading RDB file if
--dirand--dbfilenameare specified - Connecting to master if
--replicaofis specified (slave mode) - Starting the TCP server and accepting connections