A lightweight Redis-compatible in-memory data store written in C++. Supports strings, lists, and hashes with full Redis Serialization Protocol (RESP) parsing, multi-client concurrency, and periodic disk persistence.
- Redis-Compatible Protocol: Full RESP parsing support
- Multi-Client Concurrency: Each client handled in separate threads
- Data Types: Strings, Lists, and Hashes
- Persistence: Automatic disk dumps every 5 minutes and on shutdown
- TTL Support: Key expiration with lazy eviction
- Thread-Safe: Mutex-protected data stores
- C++17 (or later) compiler
- POSIX-compatible system (Linux, macOS)
- Make (optional)
# Using Makefile (recommended)
make
# Or compile manually
g++ -std=c++17 -pthread -Iinclude src/*.cpp -o my_redis_server# Default port (6379)
./my_redis_server
# Custom port
./my_redis_server 6380# Using redis-cli
redis-cli -p 6379
# Example commands
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> SET mykey "Hello World"
OK
127.0.0.1:6379> GET mykey
"Hello World"PING- Test server connectivityECHO <message>- Echo a messageFLUSHALL- Clear all data
SET <key> <value>- Store a string valueGET <key>- Retrieve a string valueDEL <key>/UNLINK <key>- Delete a keyKEYS *- List all keysTYPE <key>- Get the data type of a keyEXPIRE <key> <seconds>- Set key expirationRENAME <oldkey> <newkey>- Rename a key
LGET <key>- Get all elements from a listLLEN <key>- Get list lengthLPUSH <key> <value1> [value2 ...]- Push to list headRPUSH <key> <value1> [value2 ...]- Push to list tailLPOP <key>- Pop from list headRPOP <key>- Pop from list tailLINDEX <key> <index>- Get element at indexLSET <key> <index> <value>- Set element at indexLREM <key> <count> <value>- Remove elements
HSET <key> <field> <value>- Set hash fieldHGET <key> <field>- Get hash field valueHEXISTS <key> <field>- Check if field existsHDEL <key> <field>- Delete hash fieldHLEN <key>- Get number of fieldsHKEYS <key>- Get all field namesHVALS <key>- Get all field valuesHGETALL <key>- Get all field-value pairsHMSET <key> <field1> <value1> [field2 value2 ...]- Set multiple fields
- RedisServer: TCP socket handling and client management
- RedisDatabase: Thread-safe data storage (singleton pattern)
- RedisCommandHandler: RESP protocol parsing and command execution
- String Store:
unordered_map<string, string> - List Store:
unordered_map<string, vector<string>> - Hash Store:
unordered_map<string, unordered_map<string, string>> - Expiry Map: TTL tracking for automatic key expiration
- One thread per client connection
- Single global mutex (
db_mutex) protecting all data stores - Lazy expiration on key access
The server automatically saves data to dump.my_rdb:
- Every 300 seconds (5 minutes) via background thread
- On graceful shutdown (Ctrl+C)
- Loads existing dump file on startup
├── include/ # Header files
│ ├── RedisCommandHandler.h
│ ├── RedisDatabase.h
│ └── RedisServer.h
├── src/ # Implementation files
│ ├── RedisCommandHandler.cpp
│ ├── RedisDatabase.cpp
│ ├── RedisServer.cpp
│ └── main.cpp
├── Makefile # Build configuration
├── README.md # This file
├── Concepts,UseCases&Tests.md # Design documentation
└── test_all.sh # Test script
- Clone the repository
- Navigate to project directory
- Run
maketo build - Run
make cleanto clean build artifacts
Run the provided test script:
./test_all.shOr test manually with redis-cli or any RESP-compatible client.
- Default Port: 6379
- Persistence File:
dump.my_rdb - Auto-save Interval: 300 seconds
- Protocol: Redis RESP (REdis Serialization Protocol)
- Single-threaded command execution (per client)
- Text-based persistence format (simplified RDB)
- Memory-only storage (no disk-based datasets)
- Subset of Redis commands implemented
Server Name: my_redis_server
Default Port: 6379
Protocol: Redis RESP