A lightweight implementation of a Redis-like in-memory data store written in C++. This project demonstrates core networking concepts, data structures, multi-threading, and RESP (REdis Serialization Protocol) parsing.
- Ridham1010 (Ridham Shah - B24CS1064)
- centauri1219 (Atharv Dhuvad - B24CS1085)
- shrey-shah299 (Shrey Shah - B24CS1111)
- In-Memory Data Structures: Hash tables, lists, and nested hash maps for efficient storage
- TCP Server: Multi-threaded TCP server supporting concurrent client connections
- RESP Protocol: Full support for Redis RESP protocol parsing and encoding
- Multi-threading: Handles multiple clients simultaneously using C++ threads
- Socket Programming: Implements low-level socket operations (bind, listen, accept)
- Data Persistence: Automatic background persistence with dump/load functionality
- Key Expiration: TTL support with automatic cleanup
- Task Queue System: Distributed task queue with priority-based processing
- Web Dashboard: Real-time monitoring and task management interface
The project consists of three main components:
Core server handling socket operations, client connections, and command processing using three primary data structures:
- Key-Value Store:
unordered_map<string, string>for simple key-value pairs - List Store:
unordered_map<string, vector<string>>for list operations - Hash Store:
unordered_map<string, unordered_map<string, string>>for structured data
Interactive command-line interface for sending commands to the server via RESP protocol.
Distributed task queue with:
- Producer: Creates and queues tasks with priority levels
- Workers: Process tasks from priority queues
- Web Dashboard: Real-time visualization of task processing
- C++17 or higher
- g++ compiler
- pthread library
- Linux/Unix environment (for socket programming)
- Node.js and npm (for web dashboard only)
# Build everything (server + client)
make
# Build only server
make server
# Build only client
make client
# Clean build artifacts
make clean
# Rebuild from scratch
make rebuildcd task-queue
make
# This builds:
# - producer (task creator)
# - worker (task processor)Use this option if you want to test Redis commands interactively.
Terminal 1 - Start Redis Server:
./redis-lite
# Or with custom port:
./redis-lite 8080You should see:
Database loaded dump.my_rdb
Server is listening on port 6379...
Terminal 2 - Start Redis Client:
./redis-cli
# Or connect to custom port:
./redis-cli -p 8080Test Commands:
127.0.0.1:6379> SET username alice
OK
127.0.0.1:6379> GET username
alice
127.0.0.1:6379> LPUSH tasks task1
1
127.0.0.1:6379> HSET user:1 name John
1
127.0.0.1:6379> HGETALL user:1
name
John
127.0.0.1:6379> quit
Use this option to see the complete task queue system with real-time web dashboard.
Terminal 1 - Start Redis Server:
./redis-liteTerminal 2 - Start Workers:
cd task-queue
./worker 3This starts 3 worker threads that will process tasks from the queue.
Terminal 3 - Start Backend Server:
cd web-dashboard/backend
npm install # First time only
node server.jsYou should see:
Backend server running on http://localhost:3001
Connected to Redis-Lite at 127.0.0.1:6379
Terminal 4 - Start Frontend:
cd web-dashboard/frontend
npm install # First time only
npm startThe React development server will start and automatically open your browser to:
http://localhost:3000
Terminal 5 - Start Producer (Optional):
cd task-queue
./producerUse the interactive menu to create tasks. You can also create tasks directly from the web interface.
What you'll see in the Web Dashboard:
- Real-time Redis server status
- Task creation interface
- Worker status (idle/processing)
- Queue statistics by priority
- Live task processing updates
SET key value- Store a key-value pairGET key- Retrieve value by keyDEL key- Delete a keyKEYS- List all keysTYPE key- Get the type of value stored at keyEXPIRE key seconds- Set key expirationRENAME oldkey newkey- Rename a key
LPUSH key value- Insert at the front of listRPUSH key value- Insert at the back of listLPOP key- Remove and return first elementRPOP key- Remove and return last elementLLEN key- Get list lengthLINDEX 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 valueHGETALL key- Get all fields and valuesHDEL key field- Delete hash fieldHEXISTS key field- Check if field existsHKEYS key- Get all field namesHVALS key- Get all valuesHLEN key- Get number of fieldsHMSET key field1 value1 field2 value2- Set multiple fields
PING- Test server connectionECHO message- Echo the message backFLUSHALL- Clear all data
Redis-Lite/
├── src/
│ ├── main.cpp # Server entry point
│ ├── Redisserver.cpp # TCP server implementation
│ ├── RedisCommandHandler.cpp # Command processing and RESP parsing
│ └── RedisDatabase.cpp # Data structure implementations
├── include/
│ ├── RedisServer.h # Server header
│ ├── RedisCommandHandler.h # Command handler header
│ └── RedisDatabase.h # Database header
├── Redis-Client/
│ ├── main.cpp # Client entry point
│ ├── my_redis_cli.cpp # Client implementation
│ └── utils.cpp # Utility functions
├── task-queue/
│ ├── producer.cpp # Task creator
│ ├── worker.cpp # Task processor
│ └── redis_client.cpp # Redis client for task queue
├── web-dashboard/
│ ├── backend/
│ │ └── server.js # Express API server
│ └── frontend/
│ └── src/ # React application
├── build/ # Build artifacts (generated)
├── Makefile # Build configuration
└── README.md
- Server Initialization: Creates a TCP socket and binds to specified port (default: 6379)
- Listening: Server enters listening state, waiting for incoming client connections
- Multi-threaded Client Handling:
- For each client connection, spawns a new thread
- Each thread independently handles one client's requests
- Allows concurrent connections from multiple clients
- Command Processing:
- Receives RESP-formatted commands from client
- Parses command into tokens (command name + arguments)
- Routes to appropriate handler based on command type
- Executes operation on in-memory data structures
- Returns RESP-formatted response
- Data Persistence:
- Background thread dumps database to disk every 300 seconds
- On server startup, loads data from dump file
- On shutdown, performs final dump to preserve data
- Thread Safety: All database operations protected by mutex locks
The server implements the Redis RESP (REdis Serialization Protocol) for client-server communication:
Request Format:
*3\r\n$3\r\nSET\r\n$4\r\nname\r\n$5\r\nalice\r\n
*3- Array with 3 elements$3- Bulk string of length 3SET- Command$4- Bulk string of length 4name- Key$5- Bulk string of length 5alice- Value
Response Types:
- Simple String:
+OK\r\n - Error:
-Error message\r\n - Integer:
:42\r\n - Bulk String:
$5\r\nalice\r\n - Array:
*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n
The distributed task queue demonstrates a real-world application built on Redis-Lite:
- Producer creates tasks with metadata (type, priority, status)
- Tasks are stored as hashes:
HMSET task:1001 type email priority high status pending - Task IDs are pushed to priority-based queues:
LPUSH queue:high task:1001 - Workers continuously poll queues in priority order (critical > high > normal > low)
- Workers retrieve tasks using
LPOP, update status to "processing", perform work, then mark as "completed" - Web Dashboard queries Redis for real-time status updates via the backend API
- Structure:
unordered_map<string, string> - Time Complexity: O(1) average for SET/GET
- Use Cases: Simple key-value pairs, session tokens, configuration
- Structure:
unordered_map<string, vector<string>> - Time Complexity:
- LPUSH: O(n) (must shift elements)
- RPUSH: O(1) (append to end)
- LPOP/RPOP: O(n)/O(1)
- Use Cases: Task queues, message queues, activity feeds
- Structure:
unordered_map<string, unordered_map<string, string>> - Time Complexity: O(1) average for HSET/HGET
- Use Cases: User profiles, product details, structured entities
# Check if port is already in use
sudo lsof -ti:6379 | xargs kill -9
# Or use a different port
./redis-lite 8080# Install required packages
sudo apt-get install g++ make
# Verify C++ version (requires C++17)
g++ --version# Ensure server is running
ps aux | grep redis-lite
# Check server is listening
netstat -tuln | grep 6379# Install Node.js dependencies
cd web-dashboard/backend && npm install
cd web-dashboard/frontend && npm install
# Check backend is running on port 3001
curl http://localhost:3001/api/statusSee the LICENSE file for details.
Contributions are welcome! Feel free to submit issues and pull requests.
This project was created as an educational exercise to understand:
- Low-level network programming with sockets
- Multi-threaded server architecture
- Protocol design and implementation (RESP)
- In-memory data structure design
- Distributed systems concepts (task queues)
Note: This is an educational project to understand Redis internals and network programming concepts. For production use, please use the official Redis implementation.