A multi-threaded, persistent Redis clone built from scratch in Java.
JKRedis is a lightweight implementation of a Redis-like database server. It is built using standard Java I/O (ServerSocket) without external frameworks like Netty, designed to demonstrate deep understanding of Systems Programming, Network Protocols (TCP/RESP), and Concurrency.
- In-Memory Storage: Thread-safe key-value storage using
ConcurrentHashMap. - RESP Protocol: Full implementation of the Redis Serialization Protocol, making it compatible with official Redis clients (
redis-cli, Jedis, etc.). - Concurrent Networking: Handles multiple concurrent clients using a custom Thread Pool architecture.
-
Real-Time Pub/Sub: Implements the Publish/Subscribe messaging pattern for event-driven architectures.
-
Supports
SUBSCRIBEfor listening to channels andPUBLISHfor broadcasting. -
Uses fan-out architecture with
CopyOnWriteArrayListto safely manage concurrent subscribers without blocking publishers. -
Persistence (AOF): Implements Append-Only File logging. Data survives server crashes and is replayed on startup (Crash Recovery).
-
Expiry & Eviction (TTL): Supports
PX(milliseconds) expiration. -
Lazy Eviction: Keys checked on access.
-
Active Eviction: Background thread (Probabilistic Algorithm) cleans up expired keys every 100ms.
-
Master-Replica Replication:
-
Supports
--replicaofconfiguration. -
Implements the full PSYNC Handshake (
PINGREPLCONFPSYNCFULLRESYNC). -
Real-time command propagation from Master to Replicas.
- Language: Java 17+
- Architecture: Thread-per-client (Managed via ExecutorService).
- Storage Engine: In-memory Heap with AOF disk flushing.
JKServer: The entry point. Handles argument parsing, initialization, and the accept loop.ClientHandler: The worker logic. Parses RESP streams and executes commands.Storage: The thread-safe wrapper around the data structure (K-V Store).PubSubManager: Manages channel subscriptions and handles thread-safe message broadcasting to active socket streams.AofHandler: Manages low-level File I/O for persistence.ReplicaManager: (Master Side) Manages the registry of connected replicas for data propagation.
- Java Development Kit (JDK) 8 or higher.
- Netcat (optional, for testing) or the included
JKClient.
- Clone the repository
git clone https://github.com/yourusername/jkredis.git
cd jkredis
- Compile
javac -d out src/server/*.java src/storage/*.java src/parser/*.java
By default, the server runs on port 6379.
java -cp out server.JKServer --port 6379
To start a distributed system, run a second instance in a new terminal:
java -cp out server.JKServer --port 6380 --replicaof localhost 6379
The replica will perform a handshake, sync old data, and listen for updates.
Open two terminals to test the messaging system.
Terminal A (Subscriber):
# Connect and subscribe to the 'news' channel
nc localhost 6379
SUBSCRIBE news
Terminal A will now hang, waiting for messages.
Terminal B (Publisher):
# Publish a message to the 'news' channel
echo -e "*3\r\n$7\r\nPUBLISH\r\n$4\r\nnews\r\n$5\r\nHello\r\n" | nc localhost 6379
Result: Terminal A immediately receives the "Hello" message.
Using Netcat:
echo -e "*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\nval\r\n" | nc localhost 6379
Supported Commands:
SET key value [PX milliseconds] # Set key with optional expiry
GET key # Get value
PUBLISH channel message # Broadcast message
SUBSCRIBE channel # Listen for messages
PING # Test connection
INFO # Server stats
- Start the server.
- Run
SET user "JK". - Kill the server (Ctrl+C).
- Restart the server.
- Run
GET user.
- Result: It returns
"JK". The data was recovered fromdatabase.aof.
- Transactions (ACID): Implementing
MULTI,EXEC, andDISCARDfor atomic operations. - RDB Snapshots: Binary point-in-time backups.
- Cluster Mode: Sharding data across multiple nodes (Redis Cluster).