KeyDB

repository·main·Indexed 11 days ago

https://github.com/Snapchat/KeyDB

A high-performance, multithreaded fork of Redis designed for higher throughput and better memory efficiency. It serves as a drop-in replacement for Redis and includes advanced features such as Active Replication and FLASH storage.

Tokens
38.6K
Snippets
112
Records
172
Agent score
95%

What's inside KeyDB

  1. Overview of HdrHistogram_c in KeyDB

    main
    KeyDB includes a subset of the HdrHistogram_c library (v0.11.0). This library provides High Dynamic Range (HDR) Histograms, which are used for recording and analyzing latency distributions with high precision across a wide range of values. The implementation is based on the C version of HdrHistogram and includes the core files hdr_histogram.c, hdr_histogram.h, and hdr_atomic.c.
  2. What is KeyDB?

    main

    KeyDB is a high-performance, multithreaded fork of Redis designed for high throughput and memory efficiency. It is a drop-in replacement for Redis, maintaining full compatibility with the Redis protocol, modules, and scripts (including atomicity guarantees for transactions).

    Key features include:

    • Multithreading: Concurrent network IO and query parsing.
    • MVCC Architecture: Allows executing queries like KEYS and SCAN without blocking the database.
    • Active Replication: Simplifies failover and allows distributing writes over replicas.
    • FLASH Storage: Experimental high-performance storage option.
    • Subkey Expires: Support for expiring specific subkeys.
  3. Overview of Hiredis

    main

    Hiredis is a minimalistic C client library for the Redis database. It provides a high-level, printf-like API for sending commands and receiving replies.

    Key features include:

    • Support for the binary-safe Redis protocol (compatible with Redis version >= 1.2.0).
    • A decoupled stream parser for replies that can be reused in higher-level language bindings.
    • Multiple API types: synchronous, asynchronous, and a reply parsing API.

    Note: This version of the README reflects the master branch; for the stable v1.0.0 documentation, refer to the official release tags.

  4. Overview of KeyDB dependencies

    main

    The deps/ directory contains the following core dependencies:

    • Jemalloc: The default memory allocator on Linux, providing high performance and excellent fragmentation behavior.
    • hiredis: The official C client library for Redis, used by CLI tools and Sentinel.
    • linenoise: A readline replacement.
    • lua: A modified version of Lua 5.1 used for scripting.
  5. Handle RESP3 PUSH replies in hiredis

    main

    Redis 6.0+ introduced PUSH replies (reply-type >) which are generated spontaneously and can arrive at any time. Because they are asynchronous, they must be handled using callbacks.

    By default, hiredis installs handlers on redisContext and redisAsyncContext that intercept and automatically free these replies. If you need custom logic, you must provide a callback.

    Important Memory Management Rules:

    • For redisContext (blocking): You must call freeReplyObject(reply) inside your custom handler to prevent memory leaks.
    • For redisAsyncContext (async): You must NOT call freeReplyObject(reply) because the async engine handles freeing automatically.
    /* redisContext callback prototype */
    void my_push_handler(void *privdata, void *reply) {
        /* Handle the reply */
        freeReplyObject(reply);
    }
    
    /* redisAsyncContext callback prototype */
    void my_async_push_handler(redisAsyncContext *ac, void *reply) {
        /* Handle the reply */
        /* DO NOT call freeReplyObject(reply) here */
    }
  6. KeyDB Lua implementation details

    main

    KeyDB uses a modified version of Lua 5.1. Upgrades are handled manually by maintainers to avoid breaking existing Lua scripts.

    Key differences from official Lua 5.1:

    • The Makefile is modified to support compilers other than GCC.
    • The implementation directly links to external libraries: lua_cjson.o, lua_struct.o, lua_cmsgpack.o, and lua_bit.o.
    • A security fix is applied in ldo.c (line 498) where the check for LUA_SIGNATURE[0] is removed to prevent direct bytecode execution.
  7. Note on building jemalloc documentation

    main
    By default, the make target does not build documentation to avoid a dependency on xsltproc in packaged releases. If you require documentation to be built, you must either run make dist or use specific install_* targets (refer to the documentation for those targets).
  8. Configure Batching and Sending behavior

    main

    The client supports two modes of operation based on the batch_size and send interval settings:

    Batching Mode

    • Batch Size: The number of bytes allowed in each UDP datagram payload. If adding a new stat (plus a \n separator) would exceed this size, the current batch is enqueued and a new one starts.
    • Batch Size = 0: Disables batching. Every stat is sent immediately in a blocking fashion.
    • Batch Size > 0: Enables batching.

    Sending and Flushing

    • Asynchronous Sending: If a non-zero send interval is provided, a background thread is spawned to flush queued batches at that interval. Note that the queuing mechanism is not lock-free.
    • Manual Flushing: If batching is enabled but the send interval is set to 0, batches are not sent automatically. You must call the flush() method manually, which is a blocking call.
  9. Programmatic jemalloc performance optimization

    main

    Beyond runtime configuration, jemalloc provides programmatic interfaces for advanced performance tuning:

    • Explicit Arenas: Manually create arenas to manage locality and contention. Use mallocx() with MALLOCX_ARENA to allocate objects from a specific arena. This allows for individually tuned options (like specific decay times) for different usage patterns.
    • Extent Hooks: Customize how underlying memory is managed. This can be used to implement custom huge page management to reduce TLB misses.
    • Explicit Thread-to-Arena Binding: Bind specific threads to dedicated arenas. This is particularly beneficial for high-workload threads to reduce contention at the allocator level.
  10. How TLS connections work in KeyDB

    main
    KeyDB uses a connection abstraction layer for all socket operations, which hides I/O and read/write event handling. Unlike Redis, KeyDB provides full support for multithreading TLS connections.
  11. Control metric sampling with Frequency Rate

    main

    You can limit metrics sampling by setting a frequency rate (sample rate) when sending a metric.

    • A frequency rate of 1 (default) means all metrics are sent.
    • A frequency rate close to 1 (e.g., 0.9999) also results in minimal sampling impact.
    • For values significantly less than 1, the client will randomly reject sending the metric. The higher the frequency rate, the lower the probability of rejection.
  12. Note on building documentation

    main

    By default, the make target does not build documentation. This is to avoid a mandatory dependency on xsltproc in packaged releases.

    To build documentation, you must either:

    • Run make dist before compiling,
    • Or use specific make install_* targets (refer to the full documentation for available install targets).