Valkey GLIDE Documentation

repository·main·Indexed 20 days ago

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

An official, high-performance, cross-language client library for Valkey and Redis OSS. Built with a Rust-based core, it provides consistent and highly available connectivity across multiple programming languages, including Java (including Java 8 support), Kotlin, Scala, Node.js, and Python.

Tokens
199.8K
Snippets
691
Records
807
Agent score
72%

What's inside Valkey GLIDE

  1. Overview of the glide_ffi crate

    main
    The glide_ffi crate provides a C-compatible Foreign Function Interface (FFI) for interacting with glide-core. It acts as the bridge that allows internal wrappers written in other languages (such as Go) to integrate with the core Rust logic.
  2. Overview of Valkey GLIDE

    main

    Valkey GLIDE (General Language Independent Driver for the Enterprise) is an official open-source Valkey client library. It is designed for high performance, low latency, and high availability, using a core driver framework written in Rust with language-specific extensions.

    Key Features

    • AZ Affinity: Routes read traffic to replicas in the client's availability zone to minimize cross-zone costs and latency. (Requires Valkey 8.0+ or AWS ElastiCache for Valkey 7.2+).
    • PubSub Support: Includes automatic reconnection on topology updates/disconnection and native support for Sharded PubSub.
    • Cluster Intelligence: Supports cluster-aware multi-key commands (MGET, MSET, DEL, FLUSHALL) and a unified Cluster Scan API for iterating keys across shards.
    • Batching: Supports Pipeline and Transaction modes to reduce network roundtrips.
    • Observability: Integrated OpenTelemetry support for tracing.
    • Modern Runtime Support: Compatible with modern async frameworks (asyncio/anyio/trio in Python; TS/CJS/MJS in Node.js).
  3. Understanding the Zero-Copy Initiative in Valkey GLIDE

    main

    The Zero-Copy Initiative is a performance optimization in glide-core (specifically within the vendored redis-rs) designed to reduce per-value memory copies on the client hot path.

    Historically, both receiving (GET/MGET) and sending (SET) data involved multiple copies:

    • Receive: The parser would to_vec() payloads out of the socket buffer, and the FFI would copy them again into the caller's buffer.
    • Send: A SET value could be copied up to three times (into command data, into the packed RESP vector, and into the framed write buffer) before reaching the kernel.

    The initiative implements a multi-phase design to reduce these copies to a theoretical minimum (the kernel-to-userspace recv/send copy).

  4. Handle Transactions in the Compatibility Layer

    main

    Transactions in the compatibility layer behave differently than standard Jedis. After calling multi(), you must use the returned Transaction object to queue commands. Calling methods directly on the Jedis instance will not queue them to the transaction.

    Using the Transaction Object

    Transaction t = jedis.multi();
    Response<String> r1 = t.set("key", "value");
    Response<String> r2 = t.get("key");
    List<Object> results = t.exec();
    String value = r2.get(); // retrieve after exec()

    Using the Native GLIDE Batch API

    For commands not exposed on the Transaction object, or for non-atomic pipelining, use the native GLIDE Batch API with a GlideClient instance:

    Batch batch = new Batch(true)  // true = atomic transaction
        .set("key1", "value1")
        .get("key1");
    Object[] results = glideClient.exec(batch, false).get();
  5. Use the Client-Instance Pool (`ClientPool`) for high concurrency

    main

    The ClientPool provides a pool of independent GlideClient instances. Unlike a single multiplexed client, each borrowed client from the pool has its own dedicated connection. This eliminates multiplexer contention, making it ideal for high-concurrency workloads where commands from different threads should not share a single pipeline.

    Key behaviors:

    • LIFO reuse: The most recently returned client is borrowed next to keep caches warm.
    • Auto-reconnect: Each pooled client is a full GlideClient with built-in, transparent reconnection and state restoration (AUTH, SELECT, etc.).
    • State reset: When a client is returned, a DISCARD + SELECT <configured_db> pipeline is sent to ensure the next borrower receives a clean connection.
    • Background creation: New clients are created in the background if the pool is exhausted but below max_size.

    Important Limitation: Do not use SUBSCRIBE or PSUBSCRIBE on a pooled client. The state reset does not send UNSUBSCRIBE, which would leave the next borrower with a connection stuck in subscription mode. Use the main client's pubsub API instead.

    # No specific code snippet provided for ClientPool usage, but it is accessed via the client API.
  6. Java 8 compatibility in Valkey GLIDE

    main

    Valkey GLIDE supports Java 8 (JDK 1.8) by using compatibility utilities that replace APIs introduced in Java 9 and later. Projects targeting Java 8 should ensure their build.gradle is configured with:

    • sourceCompatibility = JavaVersion.VERSION_1_8
    • targetCompatibility = JavaVersion.VERSION_1_8
  7. How Zero-Copy Receive works (Phase 1)

    main

    Phase 1 optimizes the receive side by changing the internal representation of bulk strings from Value::BulkString(Vec<u8>) to Value::BulkString(bytes::Bytes).

    Because Bytes is a refcounted view, payloads can be direct slices of the connection's read buffer, eliminating per-value allocations and memcpy operations.

    Key mechanisms:

    • Hybrid Frame Extraction:
      • Frames $\le$ 64 KB: One memcpy into an owned Bytes to keep the codec's BytesMut unshared and reusable.
      • Frames $>$ 64 KB: Uses split_to(len).freeze() for a zero-copy allocation transfer.
    • Resumable Frame Scanner: A ScanState tracks the offset and remaining children, allowing the parser to resume scanning large multi-element frames across multiple socket reads without restarting from offset 0.
    • FFI Arena: The ResponseArena now stores Bytes instead of Vec<u8>, allowing non-buffered GET/MGET responses to pass refcounted slices directly to the language bindings.
  8. Key Migration Insights for Jedis to GLIDE

    main

    Migrating to Valkey GLIDE involves several architectural shifts regarding security and connection management:

    • GLIDE Architecture Shift: Moves from application-managed SSL to system-managed SSL with secure defaults.
    • Certificate Management: If you use custom keystores or truststores, you must migrate these to the system certificate store.
    • Protocol Selection: GLIDE automatically selects TLS 1.2+ and secure cipher suites.
    • Client Authentication: Client certificates are not supported; you must use username/password authentication instead.
  9. Understand connection pooling in the GLIDE compatibility layer

    main

    When using the Jedis 4.x compatibility layer, GLIDE manages connection pooling internally for optimized performance.

    Key Difference:

    • In Jedis 4.x, GenericObjectPoolConfig (Apache Commons Pool 2) controls min/max connections and eviction.
    • In the GLIDE compatibility layer, these GenericObjectPoolConfig parameters are ignored (though they are accepted to maintain API compatibility). GLIDE's internal pooling is optimized for performance and reliability automatically.
  10. Choose between Jedis 4.x and 5.x compatibility artifacts

    main

    Selecting the correct artifact depends on your existing codebase's dependency version:

    • Use jedis-4-compatibility when: Your application was built against Jedis 4.x (e.g., 4.0.x–4.4.x). This is specifically required if you use JedisPooled with GenericObjectPoolConfig<Connection>. Note that this layer is RESP2 only; while .protocol() is available for source compatibility, it is ignored and forced to RESP2.
    • Use jedis-compatibility (5.x-oriented) when: Your codebase targets Jedis 5.x APIs (e.g., GenericObjectPoolConfig<Object> on JedisPooled) and you require RESP3 support.
    • Either module may fit when: You only use JedisPool, UnifiedJedis, JedisCluster, or standalone Jedis with simple constructors. In this case, pick the one that matches your current major API shape.
  11. Understand Zero-Copy Receive Path (Reduced-Copy)

    main

    The receive path in Valkey GLIDE is described as reduced-copy. It aims to reach the 'one-copy floor' where data moves directly from the kernel read buffer to the caller.

    This is achieved by replacing per-bulk-string Vec allocations and memcpy operations with a slice of a single frame buffer. This provides significant performance gains, especially for multi-element responses like MGET, because it eliminates one allocation and one copy per element, sharply reducing allocator pressure.