Skip to content

UdayHE/quicksilver

Repository files navigation

πŸš€ QuickSilver

In-Memory Distributed Database

QuickSilver is an open-source high-performance, in-memory key-value store with sharding, persistence, and multi-threaded client handling.
Designed for speed, scalability, and flexibility, it supports multiple database backends (InMemoryDB, ShardedDB), and persists data to disk.

πŸ“Œ Features

βœ… In-Memory Storage – Fast key-value operations
βœ… Sharding Support – Distributes data across multiple instances
βœ… LRU Eviction – Removes least-recently used entries when full
βœ… Persistence – Saves and loads data from disk
βœ… Multi-threaded – Uses a thread pool for efficient client handling
βœ… Command Pattern – Extensible command execution
βœ… Cluster Support – Distribute data across multiple nodes
βœ… Pub/Sub System – Publish and subscribe to topics for real-time messaging
βœ… Consistent Hashing – Efficiently distributes keys across cluster nodes
βœ… TTL Support – Automatic expiration of keys after a specified time

πŸ—οΈ Architecture Overview

QuickSilver follows a modular, layered architecture designed for high performance and scalability:

Core Components

  1. Server Layer

    • Main entry point (Server.java) that initializes the database, cluster service, and client handling
    • Manages server lifecycle, including graceful shutdown with data persistence
    • Handles client connections through a thread pool for concurrent request processing
  2. Client Handling

    • ClientHandler.java manages individual client connections
    • Implements command routing and cluster redirection logic
    • Handles special commands (FLUSH, DUMP) and client lifecycle management
  3. Command Processing

    • CommandRegistry.java implements the Command Pattern for extensible operations
    • Supports both database operations (SET, GET, DEL) and pub/sub operations (PUBLISH, SUBSCRIBE, UNSUBSCRIBE)
    • Commands are stateless and can be easily extended
  4. Database Layer

    • InMemoryDB: LRU-eviction based in-memory store with TTL support
    • ShardedDB: Distributes data across multiple InMemoryDB instances using consistent hashing
    • Both implementations support persistence through serialization
  5. Clustering System

    • ClusterService: Manages cluster-wide operations and data synchronization
    • ConsistentHashing: Distributes keys across cluster nodes efficiently
    • ClusterClient: Handles inter-node communication for distributed operations
    • Automatic data synchronization across cluster nodes during startup
  6. Pub/Sub System

    • PubSubManager: Manages topic-based publish/subscribe messaging
    • Real-time message distribution to subscribed clients
    • Thread-safe subscriber management using concurrent collections
  7. Configuration & Utilities

    • Config.java: Singleton configuration manager with property file support
    • ThreadPoolManager: Centralized thread pool management with graceful shutdown
    • Utility classes for cluster operations and common functionality

πŸ“‚ Project Structure

πŸ“¦ quicksilver
β”œβ”€β”€ πŸ“‚ src
β”‚   β”œβ”€β”€ πŸ“‚ main
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ io.github.udayhe.quicksilver
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ client
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ClientHandler.java       # Handles client connections
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ cluster
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ClusterClient.java       # Sends commands to cluster nodes
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ClusterManager.java      # Manages Cluster nodes
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ClusterNode.java         # Cluster node
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ClusterService.java      # Serves the cluster
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ConsistentHashing.java   # ConsistentHashing
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ command
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ implementation
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Del.java             # DELETE command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Exit.java            # EXIT command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Flush.java           # FLUSH command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Get.java             # GET command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Set.java             # SET command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Subscribe.java       # SUBSCRIBE command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Unsubscribe.java     # UNSUBSCRIBE command
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Publish.java         # PUBLISH command
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Command.java             # Command interface
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ CommandRegistry.java     # Manages command execution
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ config
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Config.java              # Reads and manages configuration
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ constant
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Constants.java           # Application-wide constants
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ db
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ implementation
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ InMemoryDB.java      # In-memory key-value store
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ShardedDB.java       # Sharded database implementation
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ DatabaseFactory.java     # Factory to create DB instances
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ DB.java                  # Generic database interface
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ enums                     
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Command.java             # Enum for commands  
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ DBType.java              # Enum for database types
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ threads
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ThreadPoolManager.java   # Centralized thread pool manager
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ util
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ ClusterUtil.java         # Cluster related utility methods
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ Util.java                # Utility class
β”‚   β”‚   β”‚   β”œβ”€β”€ Server.java                  # Main server entry point
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ resources
β”‚   β”‚   β”‚   β”œβ”€β”€ config.properties            # Configurations (port, shards, etc.)
β”œβ”€β”€ πŸ“‚ test                                  # Unit tests
β”œβ”€β”€ πŸ“œ .gitignore                            # Git ignore rules
β”œβ”€β”€ πŸ“œ build.gradle                          # Gradle build file
β”œβ”€β”€ πŸ“œ Dockerfile                            # Docker configuration
β”œβ”€β”€ πŸ“œ gradlew                               # Gradle wrapper
β”œβ”€β”€ πŸ“œ LICENSE                               # License file
β”œβ”€β”€ πŸ“œ README.md                             # Project documentation
β”œβ”€β”€ πŸ“œ settings.gradle                       # Gradle settings

πŸš€ Getting Started

πŸ“¦ 1. Clone the Repository

git clone https://github.com/UdayHE/Quicksilver.git
cd Quicksilver

πŸ”§ 2. Build the Project

./gradlew build

⚑ 3. Run the Server

java -jar build/libs/Quicksilver-1.0-SNAPSHOT.jar

πŸ”Œ 4. Default Port: 6379
Set custom port:

java -jar build/libs/Quicksilver-1.0-SNAPSHOT.jar 7000

πŸ›  Configuration

Modify config.properties in src/main/resources/:

server.port=7000
db.type=SHARDED
shard.count=4
shard.size=100

πŸ“ Commands

Command Description Examle
SET key value Stores a value SET username uday
GET key Retrieves a value GET username
DEL key Deletes a key DEL username
FLUSH Clears all data FLUSH
EXIT Closes the connection EXIT
SUBSCRIBE topic Subscribes to a topic SUBSCRIBE news
UNSUBSCRIBE topic Unsubscribes from a topic UNSUBSCRIBE news
PUBLISH topic message Publishes a message to a topic PUBLISH news "Breaking: ..."

πŸ”— Cluster Setup

QuickSilver supports distributed clustering for high availability and horizontal scaling:

Starting Multiple Nodes

# Node 1 (Port 6379)
java -jar build/libs/Quicksilver-1.0-SNAPSHOT.jar 6379

# Node 2 (Port 6380)  
java -jar build/libs/Quicksilver-1.0-SNAPSHOT.jar 6380

# Node 3 (Port 6381)
java -jar build/libs/Quicksilver-1.0-SNAPSHOT.jar 6381

Cluster Features

  • Automatic Discovery: Nodes automatically discover and register with each other
  • Data Synchronization: Initial data sync across all cluster nodes on startup
  • Consistent Hashing: Keys are distributed across nodes using consistent hashing
  • Load Distribution: Client requests are automatically routed to the appropriate node
  • Fault Tolerance: Cluster continues operating even if individual nodes fail

Cluster Commands

All standard database commands work in cluster mode:

# Connect to any node and commands will be routed appropriately
telnet localhost 6379
SET user:1001 "John Doe"
GET user:1001

πŸ”„ Sharding Configuration

Configure sharding in config.properties:

db.type=SHARDED
db.shard.total=4
db.shard.size=100

Sharding Benefits

  • Horizontal Scaling: Distribute data across multiple shards
  • Memory Efficiency: Each shard has its own LRU cache
  • Parallel Processing: Operations can be performed in parallel across shards
  • Consistent Performance: Even distribution prevents hotspots

πŸ“Š Performance Characteristics

In-Memory Performance

  • Sub-millisecond latency for GET/SET operations
  • High throughput with thread pool optimization
  • LRU eviction prevents memory exhaustion
  • TTL support for automatic data expiration

Cluster Performance

  • Linear scaling with additional nodes
  • Consistent hashing minimizes data movement during scaling
  • Network optimization with efficient inter-node communication
  • Load balancing across cluster nodes

πŸ§ͺ Testing

Run the test suite:

./gradlew test

🐳 Docker Support

Build and run with Docker:

# Build the image
docker build -t quicksilver .

# Run a single instance
docker run -p 6379:6379 quicksilver

# Run multiple instances for clustering
docker run -p 6379:6379 --name quicksilver-1 quicksilver
docker run -p 6380:6379 --name quicksilver-2 quicksilver

πŸ“œ License

Apache License Version 2.0
https://github.com/UdayHE/Quicksilver/blob/master/LICENSE

About

Quicksilver

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published