Skip to content

Latest commit

 

History

History

README.md

Valkey GLIDE

Valkey General Language Independent Driver for the Enterprise (GLIDE), is an open-source Valkey client library. Valkey GLIDE is one of the official client libraries for Valkey, and it supports all Valkey commands. Valkey GLIDE supports Valkey 7.2 and above, and Redis open-source 6.2, 7.0 and 7.2. Application programmers use Valkey GLIDE to safely and reliably connect their applications to Valkey- and Redis OSS- compatible services. Valkey GLIDE is designed for reliability, optimized performance, and high-availability, for Valkey and Redis OSS based applications. It is sponsored and supported by AWS, and is pre-configured with best practices learned from over a decade of operating Redis OSS-compatible services used by hundreds of thousands of customers. To help ensure consistency in application development and operations, Valkey GLIDE is implemented using a core driver framework, written in Rust, with language specific extensions. This design ensures consistency in features across languages and reduces overall complexity.

Documentations

See GLIDE's Java documentation site.

Getting Started - Java Wrapper

System Requirements

The release of Valkey GLIDE was tested on the following platforms:

Linux:

  • Ubuntu 20 (x86_64/amd64 and arm64/aarch64)
  • Amazon Linux 2 (AL2) and 2023 (AL2023) (x86_64)

Note: Currently Alpine Linux / MUSL is NOT supported due to an incompatibility with a native Java component.

macOS:

  • macOS 14.7 (Apple silicon/aarch_64)
  • macOS 13.7 (x86_64/amd64)

Layout of Java code

The Java client contains the following parts:

  1. src: Rust dynamic library FFI to integrate with GLIDE core library.
  2. client: A Java-wrapper around the GLIDE core rust library and unit tests for it.
  3. jedis-compatibility: A Jedis-compatible API layer that provides drop-in replacement for existing Jedis applications.
  4. benchmark: A dedicated benchmarking tool designed to evaluate and compare the performance of Valkey GLIDE and other Java clients.
  5. integTest: An integration test sub-project for API and E2E testing.

An example app (called glide.examples.ExamplesApp) is also available under examples app, to sanity check the project.

Supported Engine Versions

Refer to the Supported Engine Versions table for details.

Installation and Setup

Prerequisites

For developers, please refer to Java's DEVELOPER.md for further instruction on how to set up your development environment.

Java Requirements

Minimum requirements: JDK 8 or later. However, JDK 11 or later is strongly recommended as Java 8 no longer receives free security updates.

Ensure that you have Java installed on your system:

echo $JAVA_HOME java -version

Note: While Java 8 is supported for compatibility with legacy applications, we strongly recommend using JDK 11 or later for production deployments due to ongoing security support.

Adding the client to your project

Refer to https://central.sonatype.com/artifact/io.valkey/valkey-glide. Once set up, you can run the basic examples.

Additionally, consider installing the Gradle plugin, OS Detector to help you determine what classifier to use.

Classifiers

There are 6 types of classifiers for Valkey GLIDE which are

osx-aarch_64 osx-x86_64 linux-aarch_64 linux-x86_64 linux_musl-aarch_64 linux_musl-x86_64 windows-x86_64 

Gradle:

  • Copy the snippet and paste it in the build.gradle dependencies section.
  • IMPORTANT must include a classifier to specify your platform.
// osx-aarch_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'osx-aarch_64' } // osx-x86_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'osx-x86_64' } // linux-aarch_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'linux-aarch_64' } // linux-x86_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'linux-x86_64' } // linux_musl-aarch_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'linux_musl-aarch_64' } // linux_musl-x86_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'linux_musl-x86_64' } // windows-x86_64 dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: 'windows-x86_64' } // with osdetector - does not work for musl plugins { id "com.google.osdetector" version "1.7.3" } dependencies { implementation group: 'io.valkey', name: 'valkey-glide', version: '1.+', classifier: osdetector.classifier }

Maven:

  • IMPORTANT must include a classifier. Please use this dependency block, or both the dependency and the extension blocks if you're using os-maven-plugin, and add it to the pom.xml file.
<!-- osx-x86_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>osx-x86_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- osx-aarch_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>osx-aarch_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- linux-aarch_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>linux-aarch_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- linux-x86_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>linux-x86_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- linux_musl-aarch_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>linux_musl-aarch_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- linux_musl-x86_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>linux_musl-x86_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- windows-x86_64 --> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>windows-x86_64</classifier> <version>[1.0.0,)</version> </dependency> <!-- with os-maven-plugin --> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> </extension> </extensions> </build> <dependencies> <dependency> <groupId>io.valkey</groupId> <artifactId>valkey-glide</artifactId> <classifier>${os.detected.classifier}</classifier> <version>[1.0.0,)</version> </dependency> </dependencies>

SBT:

  • IMPORTANT must include a classifier. Please use this dependency block and add it to the build.sbt file.
// osx-aarch_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "osx-aarch_64" // osx-x86_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "osx-x86_64" // linux-aarch_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "linux-aarch_64" // linux-x86_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "linux-x86_64" // linux_musl-aarch_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "linux_musl-aarch_64" // linux_musl-x86_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "linux_musl-x86_64" // windows-x86_64 libraryDependencies += "io.valkey" % "valkey-glide" % "1.+" classifier "windows-x86_64"

Setting up the Java module

To use Valkey GLIDE in a Java project with modules, include a module-info.java in your project.

For example, if your program is called App, you can follow this path

app/src/main/java/module-info.java

and inside the module it will specifically require the line requires glide.api;

For example, if your project has a module called playground, it would look like this

module playground { requires glide.api; }

Basic Examples

Standalone Valkey:

// You can run this example code in Main.java. import glide.api.GlideClient; import glide.api.models.configuration.NodeAddress; import glide.api.models.configuration.GlideClientConfiguration; import java.util.concurrent.ExecutionException; import static glide.api.models.GlideString.gs; public class Main { public static void main(String[] args) { runGlideExamples(); } private static void runGlideExamples() { String host = "localhost"; Integer port = 6379; boolean useSsl = false; GlideClientConfiguration config = GlideClientConfiguration.builder() .address(NodeAddress.builder().host(host).port(port).build()) .useTLS(useSsl) // It is recommended to set a timeout for your specific use case .requestTimeout(500) // 500ms timeout .build(); try (GlideClient client = GlideClient.createClient(config).get()) { System.out.println("PING: " + client.ping(gs("PING")).get()); System.out.println("PING(found you): " + client.ping( gs("found you")).get()); System.out.println("SET(apples, oranges): " + client.set(gs("apples"), gs("oranges")).get()); System.out.println("GET(apples): " + client.get(gs("apples")).get()); } catch (ExecutionException | InterruptedException e) { System.out.println("Glide example failed with an exception: "); e.printStackTrace(); } } }

Cluster Valkey:

// You can run this example code in Main.java. import glide.api.GlideClusterClient; import glide.api.models.configuration.NodeAddress; import glide.api.models.configuration.GlideClusterClientConfiguration; import glide.api.models.configuration.RequestRoutingConfiguration; import java.util.concurrent.ExecutionException; import static glide.api.models.GlideString.gs; public class Main { public static void main(String[] args) { runGlideExamples(); } private static void runGlideExamples() { String host = "localhost"; Integer port1 = 7001; Integer port2 = 7002; Integer port3 = 7003; Integer port4 = 7004; Integer port5 = 7005; Integer port6 = 7006; boolean useSsl = false; GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host(host).port(port1).port(port2).port(port3).port(port4).port(port5).port(port6).build()) .useTLS(useSsl) // It is recommended to set a timeout for your specific use case .requestTimeout(500) // 500ms timeout .build(); try (GlideClusterClient client = GlideClusterClient.createClient(config).get()) { System.out.println("PING: " + client.ping(gs("PING")).get()); System.out.println("PING(found you): " + client.ping( gs("found you")).get()); System.out.println("SET(apples, oranges): " + client.set(gs("apples"), gs("oranges")).get()); System.out.println("GET(apples): " + client.get(gs("apples")).get()); } catch (ExecutionException | InterruptedException e) { System.out.println("Glide example failed with an exception: "); e.printStackTrace(); } } }

PubSub Configuration and Monitoring

Dynamic PubSub with Reconciliation

Valkey GLIDE supports dynamic PubSub with automatic subscription reconciliation. Configure the reconciliation interval to ensure subscriptions remain synchronized:

import glide.api.GlideClient; import glide.api.models.configuration.GlideClientConfiguration; import glide.api.models.configuration.AdvancedGlideClientConfiguration; import glide.api.models.configuration.NodeAddress; GlideClientConfiguration config = GlideClientConfiguration.builder() .address(NodeAddress.builder().host("localhost").port(6379).build()) .advancedConfig( AdvancedGlideClientConfiguration.builder() .pubsubReconciliationIntervalMs(5000) // Reconcile every 5 seconds .build() ) .build(); try (GlideClient client = GlideClient.createClient(config).get()) { // Subscribe to channels dynamically client.subscribeLazy(Set.of("news", "updates")).get(); // Get subscription state var state = client.getSubscriptions().get(); System.out.println("Desired subscriptions: " + state.desiredSubscriptions); System.out.println("Actual subscriptions: " + state.actualSubscriptions); // Unsubscribe client.unsubscribeLazy(Set.of("news")).get(); }

Monitoring Subscription Health

Monitor subscription health and reconciliation status using getStatistics():

try (GlideClient client = GlideClient.createClient(config).get()) { // Subscribe to channels client.subscribe(Set.of("channel1", "channel2")).get(); // Get statistics Map<String, String> stats = client.getStatistics(); // Available metrics: // - total_connections: Number of active connections // - total_clients: Number of client instances // - total_values_compressed: Count of compressed values // - total_values_decompressed: Count of decompressed values // - total_original_bytes: Original data size before compression // - total_bytes_compressed: Compressed data size // - total_bytes_decompressed: Decompressed data size // - compression_skipped_count: Times compression was skipped // - subscription_out_of_sync_count: Failed reconciliation attempts // - subscription_last_sync_timestamp: Last successful sync (milliseconds since epoch) System.out.println("Out of sync count: " + stats.get("subscription_out_of_sync_count")); System.out.println("Last sync timestamp: " + stats.get("subscription_last_sync_timestamp")); }

Sharded PubSub (Cluster Mode, Redis 7.0+)

For cluster mode, you can use sharded PubSub channels:

import glide.api.GlideClusterClient; import glide.api.models.configuration.GlideClusterClientConfiguration; GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder() .address(NodeAddress.builder().host("localhost").port(7001).build()) .advancedConfig( AdvancedGlideClusterClientConfiguration.builder() .pubsubReconciliationIntervalMs(5000) .build() ) .build(); try (GlideClusterClient client = GlideClusterClient.createClient(config).get()) { // Subscribe to sharded channels client.ssubscribe(Set.of("shard-channel-1", "shard-channel-2")).get(); // Get subscription state var state = client.getSubscriptions().get(); System.out.println("Sharded subscriptions: " + state.actualSubscriptions.get(PubSubChannelMode.Sharded)); }

Scala and Kotlin Examples

See our Scala and Kotlin examples to learn how to use Valkey GLIDE in Scala and Kotlin projects.

Accessing tests

For more examples, you can refer to the test folder unit tests and integration tests.

Benchmarks

You can run benchmarks using ./gradlew run. You can set arguments using the args flag like:

Returns the command help output

./gradlew run --args="--help"

Runs all benchmark clients against a local instance with TLS enabled using data sizing 100 and 1000 bytes, 10 and 100 concurrent tasks, 1 and 5 parallel clients.

./gradlew run --args="--resultsFile=output --dataSize \"100 1000\" --concurrentTasks \"10 100\" --clients all --host localhost --port 6279 --clientCount \"1 5\" --tls"

Runs GLIDE client against a local cluster instance on port 52756 using data sizing 4000 bytes, and 1000 concurrent tasks.

./gradlew run --args="--resultsFile=output --dataSize \"4000\" --concurrentTasks \"1000\" --clients glide --host 127.0.0.1 --port 52746 --clusterModeEnabled"

The following arguments are accepted:

  • resultsFile: the results output file
  • concurrentTasks: number of concurrent tasks
  • clients: one of: all|jedis|lettuce|glide
  • clientCount: client count
  • host: Valkey server host url
  • port: Valkey server port number
  • tls: Valkey TLS configured

Known issues

  • Conflict in netty and protobuf internal valkey glide dependencies with project dependencies using valkey glide. Issue link: #3402. Workarounds mentioned in this issue: #3367