Understanding KeyDB: Multithreaded Architecture, Connection Management, Fastlock, and Active‑Replica
This article introduces KeyDB, a high‑performance multithreaded fork of Redis, explaining its architecture, thread model, connection management, fastlock mechanism, and active‑replica features, while providing code examples and performance comparisons, and highlighting their impact on throughput and latency.
What is KeyDB?
KeyDB is a high‑performance fork of Redis, emphasizing multithreading, memory efficiency, and high throughput.
In addition to multithreading, KeyDB offers features only available in Redis Enterprise, such as Active Replication, FLASH storage support, and direct backup to AWS S3.
KeyDB maintains full compatibility with the Redis protocol, modules, and scripting, preserving atomic guarantees for scripts and transactions. Because its development stays in sync with Redis, KeyDB is a superset of Redis features and can replace existing Redis deployments.
On identical hardware, KeyDB can execute roughly twice the queries per second of Redis while reducing latency by about 60 %. Active‑Replication simplifies hot‑standby failover, allowing writes to be distributed to replicas and enabling simple TCP‑based load balancing and failover. The performance gains reduce operational costs and complexity.
Getting into KeyDB
KeyDB originated as a fork of Redis. While Redis is a single‑threaded in‑memory key‑value store, KeyDB transforms it into a multithreaded system while remaining 100 % compatible with the Redis API.
Project Git repository: https://github.com/JohnSully/KeyDB
Public technical details are scarce; this article summarises findings from the source code.
Multithreaded Architecture
Thread Model
KeyDB splits the original Redis main thread into a main thread and multiple worker threads. Each worker thread is an I/O thread that listens on ports, accepts connections, reads data, and parses the protocol.
KeyDB uses the SO_REUSEPORT socket option so that multiple threads can bind to the same port.
Each worker thread is CPU‑affined and uses SO_INCOMING_CPU to designate the CPU that receives data.
After protocol parsing, each thread operates on in‑memory data protected by a single global lock.
The main thread is also a worker thread (index 0 in the worker array) and performs tasks that only the main thread may execute.
The main thread’s primary duties are implemented in serverCron , including:
Statistics processing
Client connection management
Database resize and resharing
AOF handling
Replication master‑slave synchronization
Cluster‑mode tasks
Connection Management
In Redis, all connection handling occurs in a single thread. KeyDB assigns each worker thread a set of connections, inserting them into a thread‑local list. A new field int iel; /* the event loop index we're registered with */ records the owning thread.
KeyDB maintains three key data structures for connection management:
clients_pending_write : thread‑local list of connections awaiting synchronous writes.
clients_pending_asyncwrite : thread‑local list of connections awaiting asynchronous writes.
clients_to_close : global list of connections that need asynchronous closure.
Separate synchronous and asynchronous queues are required because commands such as pub/sub may be issued in one thread while the subscriber resides in another.
Synchronous sending is performed entirely within the originating thread; asynchronous sending uses a pipe with file descriptors int fdCmdWrite; // write pipe and int fdCmdRead; // read pipe to transfer messages between threads.
Lock Mechanism
KeyDB implements a spin‑lock‑like mechanism called fastlock . Its core structures are:
struct ticket {
uint16_t m_active; // unlock +1
uint16_t m_avail; // lock +1
};
struct fastlock {
volatile struct ticket m_ticket;
volatile int m_pidOwner; // thread id holding the lock
volatile int m_depth; // recursion depth
};Atomic operations ( __atomic_load_2 , __atomic_fetch_add , __atomic_compare_exchange ) compare m_active and m_avail to decide lock acquisition. Two acquisition modes are provided:
try_lock : returns immediately on failure.
lock : busy‑waits, then yields with sched_yield after 1 048 576 attempts.
KeyDB combines try_lock with the event loop: a client’s dedicated lock is attempted before reading data; on failure, the thread returns to epoll_wait and retries later.
Active‑Replica
KeyDB supports a multi‑active replica mode where replicas can be writable. Each replica carries a UUID to prevent circular replication. A new rreplay API packages incremental commands with the local UUID. Keys and values include a timestamp‑based version number (timestamp shifted left 20 bits plus a 44‑bit increment) to detect conflicts; writes with older timestamps are rejected.
Reference documentation: https://docs.keydb.dev/docs/commands
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.