Valkey

repository·unstable·Indexed 12 days ago

https://github.com/valkey-io/valkey

A high-performance, open-source data structure server designed for key/value workloads. A fork of Redis, Valkey supports an extensible plugin system for new data structures and access patterns. It includes the official C client library, Libvalkey, which supports RESP2 and RESP3 protocols, standalone and cluster modes, and synchronous and asynchronous operation APIs.

Tokens
94K
Snippets
412
Records
540
Agent score
98%

What's inside Valkey

  1. Overview of libvalkey Standalone API

    unstable

    The libvalkey library provides both synchronous and asynchronous APIs for interacting with Valkey in standalone (non-cluster) mode.

    • Synchronous API: Designed for straightforward, blocking command execution. It includes features like connection management, command execution, reply handling, pipelining, and reader configuration.
    • Asynchronous API: Designed for non-blocking operations.

    Note: This documentation is a guide and not a complete reference; for exhaustive details, refer to the source code.

  2. Overview of Valkey Dependencies

    unstable

    Valkey relies on several vendored dependencies for memory management, client communication, scripting, and performance tracking. Note that the operating system's libc is expected to be provided by the host environment and is not included in this directory.

    Key dependencies include:

    • Jemalloc: The default memory allocator on Linux, chosen for high performance and low fragmentation.
    • libvalkey: The official C client library used by valkey-cli, valkey-benchmark, and Valkey Sentinel.
    • linenoise: A readline replacement for command-line input.
    • lua: A customized version of Lua 5.1 used for scripting, including security patches and performance enhancements (like MurmurHash3 for large strings).
    • hdr_histogram: Used for tracking per-command latency histograms.
    • ffc.h: A C99 port of the fast_float library for efficient string-to-float conversion.
    • gtest-parallel: A script for running GoogleTest suites in parallel.
  3. Overview of HdrHistogram_c

    unstable

    HdrHistogram_c is a C port of the High Dynamic Range (HDR) Histogram. It provides a subset of the functionality found in the Java implementation, specifically designed for recording values with high precision across a wide range.

    Supported Features:

    • Standard histogram with 64-bit counts (32-bit and 16-bit counts are not supported).
    • All iterator types (all values, recorded, percentiles, linear, and logarithmic).
    • Histogram serialization (encoding version 1.2, decoding versions 1.0-1.2).
    • Reader/writer phaser and interval recorder.

    Limitations:

    • Does not support auto-resizing of histograms.
    • Does not support double histograms, atomic/concurrent histograms, or 16/32 bit histograms.
  4. Use the Lua 5.1 Scripting Module in Valkey

    unstable

    The Lua 5.1 Scripting Module allows you to execute Lua scripts directly on the Valkey server. This enables atomic execution of complex operations, reduces network round trips, and allows for server-side data processing. Scripts run in a sandboxed environment with access to Valkey data structures and a subset of the Lua standard library.

    You can execute scripts using the following commands:

    • EVAL: Executes a script.
    • FCALL: Executes a script (typically used for pre-loaded scripts).
  5. Features of Libvalkey

    unstable

    Libvalkey provides the following capabilities:

    • Generic Command Execution: Commands are executed using a printf-like invocation style.
    • Protocol Support: Supports both RESP2 and RESP3.
    • Operation Modes: Supports both synchronous and asynchronous operations.
    • Connection Options: Optional support for MPTCP, TLS, and RDMA connections.
    • Asynchronous API: Supports multiple event libraries.
    • Deployment Modes: Supports both standalone and cluster mode operation.
    • Build Systems: Can be compiled using either make or CMake.
  6. Understand the I/O Job Lifecycle

    unstable

    The lifecycle of an I/O job follows this flow:

    1. Dispatch (Main Thread): The main thread calls a try*ToIOThreads() helper. It validates eligibility (e.g., checking if the client is already in flight), snapshots necessary state, and enqueues the job into io_shared_inbox or io_private_inbox[i].
    2. Execution (Worker Thread): The worker's IOThreadMain loop untags the pointer, dispatches the job, and executes the handler (performing pure transport or memory work). It then increments io_jobs_finished.
    3. Response (Worker → Main): If a completion is required, the worker sends a JobResult via the io_shared_outbox.
    4. Completion (Main Thread): The main thread calls processIOThreadsResponses() to dequeue results and apply state changes (like reinstalling handlers).
  7. Understand jemalloc profiling sampling and performance

    unstable

    jemalloc uses sampling to minimize the high overhead of recording allocation metadata (walking the stack, allocating storage, and acquiring locks). Instead of recording every allocation, it samples a fraction of them.

    To optimize the 'fast-path' (the code executed during every allocation), jemalloc uses Fast Bernoulli sampling via a geometric distribution. Instead of generating a random number for every single allocation, it generates a random number once per successful sample and uses a counter to skip a calculated number of subsequent allocations. This significantly reduces the cost of random-number generation and floating-point operations in the hot path.

  8. Understand Atomic Slot Migration (ASM)

    unstable

    Atomic Slot Migration (ASM) is a mechanism for migrating hash slots between nodes in a Valkey cluster. It replaces the older CLUSTER SETSLOT IMPORTING/MIGRATING and MIGRATE workflow.

    ASM provides a seamless and atomic handover by:

    • Slot-Based Replication: Using Primary-Replica replication primitives scoped strictly to the migrating slots.
    • Atomic Ownership Transfer: Using a coordinated process similar to a Manual Failover to ensure the final handover is atomic.
    • Continuous Availability: The source node continues to serve business requests and retains data throughout the migration, only cutting over traffic to the target node after the atomic transfer is complete.
  9. Handling multi-key commands in Valkey Cluster

    unstable

    Libvalkey has removed support for automatically splitting multi-key commands (like DEL, EXISTS, MGET, and MSET) across multiple slots. This change was made to ensure atomicity and reduce complexity.

    Required Action: You must manually partition keys by slot before sending commands. Use valkeyClusterGetSlotByKey to determine the slot, then construct and send individual commands using valkeyClusterCommand or equivalent calls for each required slot.

    // Example logic for manual partitioning
    // 1. Get slot for key
    // 2. Use valkeyClusterGetSlotByKey(key)
    // 3. Construct new commands and send via valkeyClusterCommand
  10. Understanding jemalloc profiling output and unbiasing

    unstable

    jemalloc uses a specific trick to ensure that profiling tools like jeprof report accurate, unbiased numbers for space consumption.

    Internally, jemalloc performs unbiasing on a per-allocation basis. However, to maintain backward compatibility with jeprof and other tools that expect specific data formats, jemalloc does not surface these unbiased numbers directly in the raw dump. Instead, it manipulates the values written to the profiling dump so that when jeprof processes them, the resulting output matches the true, unbiased numbers.

    Note for developers: Because of this 'trickery', the raw profiling dump output may appear incorrect or biased to a human reader, even though the final report generated by jeprof is mathematically correct.