βββββββββββ ββββ βββββ βββββ ββββ βββββ βββββ βββββββββββββββββ βββββ βββββ ββββ βββββ βββββ ββββ β β ββββ ββββββ βββββ ββββββββ ββββ βββ ββββ ββββ ββββββββ ββββ ββββββββ βββββ βββββββββ ββββββββ ββββ ββββ ββββββββ ββββ βββββββ βββββββ ββββ ββββ βββββββββ βββββ βββ ββββ β ββββ ββββββββ βββββββ ββββ ββββ ββββ βββββ βββββββββ βββββ βββββββββββββββ ββββββ ββββ βββββ βββββ ββββββ βββββ βββββ βββββ ββββββββ ββββββ ββββ βββββ βββββ ββββ βββ
A learning-focused systems programming project demonstrating database internals, network protocols, and concurrent programming in Rust
Features β’ Architecture β’ Getting Started β’ Commands β’ What I Learned
FlashKV is a Redis-compatible, in-memory key-value database that I built from scratch to deeply understand systems programming concepts. This isn't just another Redis cloneβit's a comprehensive learning journey through database internals, network programming, protocol design, and concurrent systems.
I wanted to go beyond tutorials and actually implement the core systems that power modern databases:
- How do databases handle thousands of concurrent connections? β Built an async TCP server with Tokio
- How do protocols like Redis communicate efficiently? β Implemented a zero-copy RESP parser
- How do you make data structures thread-safe without killing performance? β Designed a sharded storage engine
- How do databases handle key expiration? β Created a dual-strategy expiry system
π‘ This project comes with 15 detailed documentation files explaining every design decision, from Rust fundamentals to advanced concurrency patterns.
| Feature | Description |
|---|---|
| Redis Protocol Compatible | Works with redis-cli, Telnet, and any Redis client library |
| Thread-Safe Concurrent Access | 64-shard architecture allowing parallel reads/writes |
| TTL & Auto-Expiry | Keys can expire automatically with lazy + active cleanup |
| Multiple Data Types | Strings and Lists with full Redis-compatible operations |
| Pattern Matching | KEYS command with glob-style pattern support (*, ?, [abc]) |
| Built-in Statistics | Real-time metrics for ops/second, memory usage, and more |
| Component | Implementation |
|---|---|
| Async Runtime | Tokio for handling 10,000+ concurrent connections |
| Zero-Copy Parsing | bytes::Bytes for efficient memory handling |
| Protocol | Full RESP (Redis Serialization Protocol) + inline commands |
| Concurrency | Arc<RwLock> with sharding to minimize contention |
| Background Tasks | Adaptive expiry sweeper that adjusts based on load |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FlashKV β
β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β TCP Server ββββββΆβ Connection ββββββΆβ Command β β
β β (Listener) β β Handler β β Handler β β
β β β β β β β β
β β β’ Accepts β β β’ Per-client β β β’ Parses β β
β β connectionsβ β read loop β β commands β β
β β β’ Spawns β β β’ Buffered β β β’ Dispatches β β
β β tasks β β I/O β β to storage β β
β ββββββββββββββββ ββββββββββββββββ ββββββββ¬ββββββββ β
β β β
β βββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββββ β
β β βΌ β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β StorageEngine β β β
β β β β β β
β β β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β β β
β β β β Shard 0 β β Shard 1 β β Shard 2 β β ... β β β β
β β β β βββββββ β β βββββββ β β βββββββ β β 64 β β β β
β β β β RwLock β β RwLock β β RwLock β β shards β β β β
β β β β HashMap β β HashMap β β HashMap β β β β β β
β β β β(strings)β β(strings)β β(strings)β β β β β β
β β β β HashMap β β HashMap β β HashMap β β β β β β
β β β β (lists) β β (lists) β β (lists) β β β β β β
β β β βββββββββββ βββββββββββ βββββββββββ βββββββββββ β β β
β β β β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β β β² β β
β β β β β
β β ββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββ β β
β β β ExpirySweeper (Background) β β β
β β β β’ Adaptive interval (100ms - 1s based on load) β β β
β β β β’ Scans shards for expired keys β β β
β β β β’ Graceful shutdown support β β β
β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β RESP Protocol Parser β β
β β β’ Zero-copy parsing with bytes::Bytes β β
β β β’ Supports: Simple Strings, Errors, Integers, Bulk Strings, Arrays β β
β β β’ Inline command support (plain text like "SET key value") β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Decision | Why |
|---|---|
| 64 Shards | Reduces lock contentionβkeys are distributed by hash, allowing parallel access |
| RwLock per Shard | Multiple readers can access data simultaneously; writers get exclusive access |
| Separate List Storage | Type safetyβprevents accidental string operations on lists |
| Lazy + Active Expiry | Lazy catches expired keys on access; active reclaims memory for untouched keys |
| VecDeque for Lists | O(1) push/pop on both ends, perfect for LPUSH/RPUSH/LPOP/RPOP |
- Rust 1.75+ (Install Rust)
# Clone the repository
git clone https://github.com/yourusername/flashkv.git
cd flashkv
# Build in release mode (optimized)
cargo build --release
# Run tests (69 tests covering all functionality)
cargo test# Start with defaults (127.0.0.1:6379)
cargo run --release
# Or with custom settings
./target/release/flashkv --host 0.0.0.0 --port 6380Option 1: Using redis-cli
redis-cli -p 6379
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> SET greeting "Hello, World!"
OK
127.0.0.1:6379> GET greeting
"Hello, World!"Option 2: Using Telnet (inline commands)
telnet localhost 6379
set name Ariz
+OK
get name
$4
Ariz| Command | Syntax | Description |
|---|---|---|
SET |
SET key value [EX s] [PX ms] [NX|XX] [GET] |
Set a key with optional expiry and conditions |
GET |
GET key |
Get value by key |
DEL |
DEL key [key ...] |
Delete one or more keys |
EXISTS |
EXISTS key [key ...] |
Check if keys exist |
INCR |
INCR key |
Increment integer value by 1 |
INCRBY |
INCRBY key delta |
Increment by specified amount |
DECR |
DECR key |
Decrement integer value by 1 |
DECRBY |
DECRBY key delta |
Decrement by specified amount |
APPEND |
APPEND key value |
Append to existing string |
STRLEN |
STRLEN key |
Get string length |
MSET |
MSET k1 v1 [k2 v2 ...] |
Set multiple keys atomically |
MGET |
MGET k1 [k2 ...] |
Get multiple values |
SETNX |
SETNX key value |
Set only if key doesn't exist |
SETEX |
SETEX key seconds value |
Set with expiry in seconds |
PSETEX |
PSETEX key ms value |
Set with expiry in milliseconds |
GETSET |
GETSET key value |
Set new value, return old |
GETDEL |
GETDEL key |
Get value and delete key |
| Command | Syntax | Description |
|---|---|---|
LPUSH |
LPUSH key val [val ...] |
Push to head of list |
RPUSH |
RPUSH key val [val ...] |
Push to tail of list |
LPOP |
LPOP key |
Remove and return from head |
RPOP |
RPOP key |
Remove and return from tail |
LLEN |
LLEN key |
Get list length |
LINDEX |
LINDEX key index |
Get element by index (supports negative) |
LRANGE |
LRANGE key start stop |
Get range of elements |
LSET |
LSET key index value |
Set element at index |
LREM |
LREM key count value |
Remove elements by value |
| Command | Syntax | Description |
|---|---|---|
EXPIRE |
EXPIRE key seconds |
Set TTL in seconds |
PEXPIRE |
PEXPIRE key ms |
Set TTL in milliseconds |
EXPIREAT |
EXPIREAT key timestamp |
Set expiry at Unix timestamp |
TTL |
TTL key |
Get remaining TTL in seconds |
PTTL |
PTTL key |
Get remaining TTL in milliseconds |
PERSIST |
PERSIST key |
Remove expiry from key |
KEYS |
KEYS pattern |
Find keys matching pattern |
TYPE |
TYPE key |
Get type (string/list/none) |
RENAME |
RENAME key newkey |
Rename a key |
RENAMENX |
RENAMENX key newkey |
Rename only if new key doesn't exist |
| Command | Syntax | Description |
|---|---|---|
PING |
PING [message] |
Test connection |
ECHO |
ECHO message |
Echo message back |
INFO |
INFO [section] |
Server information |
DBSIZE |
DBSIZE |
Number of keys |
FLUSHDB |
FLUSHDB |
Clear entire database |
FLUSHALL |
FLUSHALL |
Clear entire database |
COMMAND |
COMMAND |
List available commands |
CONFIG |
CONFIG GET param |
Get configuration |
TIME |
TIME |
Server time |
DEBUG |
DEBUG SLEEP seconds |
Debug utilities |
flashkv/
βββ src/
β βββ main.rs # Entry point, CLI parsing, TCP server setup
β βββ lib.rs # Public API exports
β β
β βββ protocol/ # RESP Protocol Implementation
β β βββ mod.rs # Module exports
β β βββ types.rs # RespValue enum, serialization
β β βββ parser.rs # Zero-copy parser, inline command support
β β
β βββ storage/ # Storage Engine
β β βββ mod.rs # Module exports
β β βββ engine.rs # Sharded HashMap, Entry/ListEntry, all operations
β β βββ expiry.rs # Background sweeper task
β β
β βββ commands/ # Command Handlers
β β βββ mod.rs # Module exports
β β βββ handler.rs # 46 command implementations
β β
β βββ connection/ # Connection Management
β βββ mod.rs # Module exports
β βββ handler.rs # Per-client read loop, stats
β
βββ docs/ # Comprehensive Documentation (15 files)
β βββ 00_INDEX.md # Documentation index
β βββ 01_RUST_FUNDAMENTALS.md # Rust concepts used in the project
β βββ 02_ASYNC_PROGRAMMING.md # Tokio, async/await patterns
β βββ 03_NETWORKING_BASICS.md # TCP, sockets, buffered I/O
β βββ 04_RESP_PROTOCOL.md # Redis protocol specification
β βββ 05_PROTOCOL_TYPES.md # RespValue implementation
β βββ 06_PROTOCOL_PARSER.md # Parser design and zero-copy
β βββ 07_CONCURRENCY.md # Arc, RwLock, sharding strategies
β βββ 08_STORAGE_ENGINE.md # Storage design and operations
β βββ 09_EXPIRY_SWEEPER.md # Background task implementation
β βββ 10_COMMAND_HANDLER.md # Command dispatch and handlers
β βββ 11_CONNECTION_HANDLER.md# Client connection lifecycle
β βββ 12_MAIN_SERVER.md # Server bootstrap and shutdown
β βββ 13_LIB_EXPORTS.md # Public API design
β βββ 14_BENCHMARKING.md # Performance testing guide
β βββ 15_EXERCISES.md # Extension exercises
β
βββ benches/
β βββ throughput.rs # Criterion benchmarks
β
βββ Cargo.toml # Dependencies and metadata
βββ README.md # You are here!
Building FlashKV taught me deep, practical knowledge in several areas:
| Concept | What I Implemented |
|---|---|
| Memory Management | Zero-copy parsing with bytes::Bytes, avoiding allocations in hot paths |
| Concurrency | Sharded locks allowing parallel access without data races |
| Background Tasks | Graceful spawning and shutdown of async tasks |
| Resource Cleanup | Proper cleanup on connection drop and server shutdown |
| Concept | What I Implemented |
|---|---|
| TCP Servers | Async listener accepting thousands of connections |
| Buffered I/O | Efficient reading with BytesMut buffers |
| Protocol Parsing | Incremental parser handling partial data |
| Connection Lifecycle | Per-client state management |
| Concept | What I Implemented |
|---|---|
| Storage Engines | Thread-safe HashMap with TTL support |
| Data Types | Strings and Lists with type-safe operations |
| Expiry Mechanisms | Lazy deletion + active background sweeping |
| Statistics Tracking | Atomic counters for real-time metrics |
| Concept | Where I Used It |
|---|---|
| Ownership & Borrowing | Throughoutβespecially in the parser and storage |
| Lifetimes | Parser returning references into buffers |
| Traits | Debug, Clone, Default implementations |
| Error Handling | Result, Option, thiserror for custom errors |
| Async/Await | Tokio-based server and background tasks |
| Smart Pointers | Arc, Box for shared ownership |
| Interior Mutability | RwLock for concurrent access |
Run benchmarks:
cargo benchOr use Redis's benchmark tool:
# Start FlashKV
cargo run --release &
# Run benchmark
redis-benchmark -t set,get,incr -n 100000 -q -p 6379Expected results on modern hardware:
SET: ~150,000 requests/second
GET: ~200,000 requests/second
INCR: ~180,000 requests/second
The following features could be added to extend FlashKV:
- Persistence - RDB snapshots and AOF logging
- Pub/Sub - Publish/Subscribe messaging
- Transactions - MULTI/EXEC command blocks
- More Data Types - Sets, Sorted Sets, Hashes
- Cluster Mode - Distributed sharding across nodes
- Lua Scripting - Server-side scripting support
This project includes 15 detailed documentation files covering:
- Rust Fundamentals - Ownership, borrowing, lifetimes
- Async Programming - Tokio, futures, task spawning
- Networking - TCP, buffered I/O, connection handling
- Protocol Design - RESP specification and parsing
- Concurrency - Locks, atomics, sharding strategies
- Storage Design - Data structures, expiry, statistics
- And more...
Each file includes code examples, diagrams, and exercises.
Contributions are welcome! Whether it's:
- Bug fixes
- New features
- Documentation improvements
- Additional tests
MIT License - feel free to use this for learning and building!
This project was built as a learning exercise to understand database internals, network programming, and systems design.