A lightweight Redis-inspired key-value store written in Rust for learning systems programming concepts. The project focuses on implementing core database components from scratch, including command parsing, persistence, TCP networking, and concurrent client handling using only the Rust standard library.
- In-memory key-value storage using
HashMap - TCP server for handling remote clients
- Interactive TCP client
- Concurrent client support using threads
- Shared state with
Arc<Mutex<Store>> - Append-only persistence log
- Automatic state recovery on startup
- Basic Redis-inspired commands
| Command | Description |
|---|---|
SET <key> <value> |
Store a key-value pair |
GET <key> |
Retrieve the value of a key |
DEL <key> |
Delete a key |
EXISTS <key> |
Check whether a key exists |
CLEAR |
Remove all keys from the database |
EXIT |
Close the current client connection |
src/
├── main.rs # Entry point
├── server.rs # TCP server and client handling
├── client.rs # Interactive TCP client
├── parser.rs # Command parser
└── collect.rs # Storage engine and persistence
Client
│
│ TCP
▼
TcpListener
│
Incoming Stream
│
Thread per Client
│
Arc<Mutex<Store>>
│
In-Memory Store
│
Append-Only Log
Each client connection is processed on its own thread while all threads share a single in-memory store protected by a mutex.
The database maintains an append-only log (Storage.txt).
State-changing commands are appended to the log and replayed during startup to reconstruct the in-memory database.
This approach provides simple persistence without implementing a binary snapshot format.
Each incoming TCP connection is handled by an independent thread.
The database is shared between threads using:
Arcfor shared ownershipMutexfor synchronized access
This allows multiple clients to read and modify the same database concurrently while preventing data races.
cargo buildStart the server:
cargo runStart the client:
rustc client.rs
./clientAlternatively, connect using netcat:
nc 127.0.0.1 7878SET name rehmat
OK
GET name
rehmat
EXISTS name
true
DEL name
OK
GET name
(nil)
- Supports only string keys and values
- Uses a custom text-based protocol (RESP not yet implemented)
- Single-process server
- Thread-per-client concurrency model
- Append-only persistence without snapshotting
- No authentication
- No key expiration (TTL)
- RESP protocol implementation
redis-clicompatibility- TTL support
- Snapshot persistence
- Additional Redis commands
- Improved persistence format
- Async networking using Tokio