Migration Guide Jedis - valkey-io/valkey-glide GitHub Wiki
This guide provides a side-by-side comparison of how to migrate common Valkey commands from Jedis to Glide.
To use Valkey Glide, you must include a classifier to specify your platform architecture.
This section includes setup instructions for Gradle, Maven, and SBT, with or without OS detection tools.
Dependency Instructions
osx-aarch_64
linux-aarch_64
linux-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'
}
// 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'
}
// with osdetector
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 usingos-maven-plugin
, and add it to the pom.xml file.
<!--osx-aarch_64-->
<dependency>
<groupId>io.valkey</groupId>
<artifactId>valkey-glide</artifactId>
<classifier>osx-aarch_64</classifier>
<version>[1.0.0,2.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,2.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,2.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,2.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"
// 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"
- In Jedis, multiple constructors allow for various connection configurations.
- In Glide, connections are established through a single configuration object, which comes pre-configured with best practices.
Glide requires minimal configuration changes, typically for:
- Timeout settings
- TLS
- Read from replica
- User authentication (username & password)
For advanced configurations, refer to the Glide Wiki - Java.
No Connection Pool Needed: Glide’s async API efficiently handles multiple requests with a single connection.
Standalone Mode
Jedis
import redis.clients.jedis.Jedis;
Jedis jedis = new Jedis("localhost", 6379);
Glide
import glide.api.GlideClient;
import glide.api.models.configuration.GlideClientConfiguration;
GlideClientConfiguration config = GlideClientConfiguration.builder()
.address(NodeAddress.builder()
.host("localhost")
.port(6379)
.build())
.build();
GlideClient glideClient = GlideClient.createClient(config).get();
Cluster Mode
Jedis
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.JedisCluster;
JedisCluster jedisCluster = new JedisCluster(
Set.of(new HostAndPort(HOST, PORT)),
DefaultJedisClientConfig.builder()
.ssl(USE_SSL)
.build()
);
Glide
import glide.api.GlideClusterClient;
import glide.api.models.configuration.GlideClusterClientConfiguration;
import glide.api.models.configuration.NodeAddress;
GlideClusterClientConfiguration config =
GlideClusterClientConfiguration.builder()
.address(NodeAddress.builder()
.host(HOST)
.port(PORT)
.build())
.useTLS(USE_SSL)
.build();
GlideClusterClient glideClusterClient = GlideClusterClient.createClient(clusterConfig).get();
Jedis vs. Glide Constructor Parameters
The table below compares Jedis constructors with Glide configuration parameters:
Jedis Constructor | Equivalent Glide Configuration |
---|---|
HostAndPort(String host, int port) |
.address(NodeAddress.builder().host(String host).port(Integer port).build()) |
int socketTimeout |
.requestTimeout(Integer requestTimeout) |
String password, String user |
.credentials(ServerCredentials.builder().username(String user).password(String pwd).build()) |
String clientName |
.clientName(String clientName) |
boolean ssl |
.useTLS(useTLS) |
Set<HostAndPort> clusterNodes |
N/A |
Cache clientSideCache |
N/A |
CacheConfig cacheConfig |
N/A |
Duration topologyRefreshPeriod |
N/A |
Duration maxTotalRetriesDuration |
N/A |
JedisClientConfig clientConfig |
N/A |
HostAndPortMapper hostAndPortMap |
N/A |
int maxAttempts |
N/A |
GenericObjectPoolConfig<Connection> poolConfig |
N/A |
Advanced configuration
-
Standalone Mode
.advancedConfiguration(AdvancedGlideClientConfiguration.builder()
-
Cluster Mode
.advancedConfiguration(AdvancedGlideClusterClientConfiguration.builder()
Jedis Constructor | Equivalent Glide Configuration |
---|---|
int connectionTimeout |
.connectionTimeout(Integer connectionTimeout) |
Below is a list of the most commonly used Valkey commands in Glide clients and how they compare to Jedis.
Note: Jedis is synchronous, while Glide is asynchronous. Most Glide commands return a CompletableFuture<T>
, so you'll need to call .get()
and handle exceptions like InterruptedException
or ExecutionException
.
AUTH | EXPIRE | MGET |
DECR | GET | MULTI |
INCRBY | HSET | RPUSH |
DEL | INCR | SCAN |
EVAL | INCRBY | SELECT |
EVALSHA | INFO | SET |
EXISTS | LPUSH | SETEX |
SET & GET
- Both Jedis and Glide support this in the same way.
Jedis
// Set a key-value pair
jedis.set("key", "value");
// Retrieve the value
String value = jedis.get("key"); // value = "value"
Glide
// Set a key-value pair
glideClient.set("key", "value").get();
// Glide uses async calls, so we call .get() to retrieve the result
String value = glideClient.get("key").get(); // value = "value"
Delete (DEL)
The DEL
command removes one or more keys from Valkey.
- In Jedis,
del()
takes a single key or multiple keys. - In Glide,
del()
requires an array (String[]
).
Jedis
String[] keys = { "key1", "key2" };
jedis.del(keys);
String value1 = jedis.get("key1"); // null
String value2 = jedis.get("key2"); // null
Glide
String[] keys = { "key1", "key2" };
glideClient.del(keys).get();
String value1 = glideClient.get("key1").get(); // null
String value2 = glideClient.get("key2").get(); // null
EXISTS
The EXISTS
command checks if a key exists in Valkey.
- In Jedis, exists(String key) returns true if the key exists. If given multiple keys (String... keys), it returns the number of existing keys.
- In Glide,
exists()
takes a list of keys (String[]
) and returns a Long indicating how many of the provided keys exist.
Single key
Jedis
boolean res1 = jedis.exists("new_key"); // false
// Set a key-value pair
jedis.set("new_key", "value");
boolean res2 = jedis.exists("new_key"); // true
Glide
// Check if the key exists and return the number of keys that exist
Long res = glideClient.exists(new String[] { "new_key" }).get(); // 0
// Set a key-value pair
glideClient.set("new_key", "value").get();
// Check again
Long res2 = glideClient.exists(new String[] { "new_key" }).get(); // 1
Multiple keys
Jedis
String[] keys = { "new_key1", "new_key2" };
long res1 = jedis.exists(keys); // 0
// Set the new keys
jedis.set("new_key1", "value1");
jedis.set("new_key2", "value2");
long res2 = jedis.exists(keys); // 2
Glide
String[] keys = { "new_key1", "new_key2" };
long res1 = glideClient.exists(keys).get(); // 0
// Set the new keys
glideClient.set("new_key1", "value1").get();
glideClient.set("new_key2", "value2").get();
long res2 = glideClient.exists(keys).get(); // 2
Increment (INCR) / Decrement (DECR)
The INCR
command increments the value of a key by 1, while DECR
decrements it by 1.
- Both Jedis and Glide support these commands with the same syntax and behavior.
- The key must contain an integer value, otherwise, Valkey will return an error.
Jedis
jedis.set("key", "1");
jedis.incr("key"); // key = 2
jedis.decr("key"); // key = 1
Glide
glideClient.set("key", "1").get();
glideClient.incr("key").get(); // key = 2
glideClient.decr("key").get(); // key = 1
INCRBY / DECRBY
The INCRBY
command increases the value of a key by a specified amount.
- Works the same way in both Jedis and Glide.
Jedis
jedis.set("counter", "0");
long counter = jedis.incrBy("counter", 3); // counter: 3
counter = jedis.decrBy("counter", 2); // counter: 1
Glide
glideClient.set("counter", "0").get();
long counter = glideClient.incrBy("counter", 3).get(); // counter: 3
counter = glideClient.decrBy("counter", 2).get(); // counter: 1
MGET
The MGET
command retrieves the values of multiple keys from Valkey.
- In Jedis,
mget()
returns aList<String>
. - In Glide,
mget()
returns aString[]
.
Jedis
String[] keys = new String[] { "key1", "key2", "key3" };
List<String> values = jedis.mget(keys);
Glide
String[] keys = new String[] {"key1", "key2", "key3"};
String[] values = glideClient.mget(keys).get();
HSET
The HSET
command sets multiple field-value pairs in a hash.
- Both Jedis and Glide support this in the same way.
Jedis
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
long result = jedis.hset("my_hash", map);
System.out.println(result); // Output: 2 - Indicates that 2 fields were successfully set in the hash "my_hash"
Glide
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
long result = glideClient.hset("my_hash", map).get();
System.out.println(result); // Output: 2 - Indicates that 2 fields were successfully set in the hash "my_hash"
SETEX
The SETEX
command sets a key with an expiration time.
- In Jedis,
setex()
is a dedicated function. - In Glide, expiration is handled using
SetOptions
within theset()
command.
Jedis
jedis.setex("key", 1, "value");
Glide
SetOptions options = SetOptions.builder().expiry(Expiry.Seconds(1L)).build();
glideClient.set("key", "value", options);
LPUSH / RPUSH
The LPUSH
and RPUSH
commands add elements to a Valkey list.
- LPUSH inserts at the beginning.
- RPUSH inserts at the end.
- This command works the same way in both Jedis and Glide.
Jedis
String[] strings = {"key1", "key2", "key3"};
long length_of_list = jedis.lpush("list", strings); // length_of_list = 3
Glide
String[] elements = {"key1", "key2", "key3"};
long length_of_list = glideClient.lpush("list", elements).get(); // length_of_list = 3
EXPIRE
The EXPIRE
command sets a time-to-live (TTL) for a key.
- Both Jedis and Glide support this in the same way.
Jedis
jedis.expire("key", 2);
Glide
glideClient.expire("key", 2).get();
Transactions (MULTI & EXEC)
The MULTI
command starts a Valkey transaction.
The EXEC
command executes all queued commands in the transaction.
- In Jedis, transactions are started using
jedis.multi()
. - In Glide, transactions are represented as a
Transaction
object.
Standalone Mode
Jedis
// Start a transaction
Transaction transaction = jedis.multi();
// Add commands to the transaction
transaction.set("key", "1");
transaction.incr("key");
transaction.get("key");
// Execute the transaction
List<Object> result = transaction.exec();
System.out.println(result); // Output: [OK, 2, 2]
Glide
import glide.api.models.Transaction;
// Initialize a transaction object
Transaction transaction = new Transaction();
// Add commands to the transaction
transaction.set("key", "1");
transaction.incr("key");
transaction.get("key");
// Execute the transaction
Object[] result = glideClient.exec(transaction).get();
System.out.println(Arrays.toString(result)); // Output: [OK, 2, 2]
Cluster Mode
Jedis
import redis.clients.jedis.AbstractTransaction;
// Initialize a cluster transaction object
AbstractTransaction transaction = jedisCluster.multi();
// Add commands to the transaction
transaction.set("key", "value");
transaction.get("key");
// Execute the transaction
List<Object> result = transaction.exec();
System.out.println(result); // Output: [OK, "value"]
Glide
import glide.api.models.ClusterTransaction;
// Initialize a cluster transaction object
ClusterTransaction transaction = new ClusterTransaction();
// Chain commands
transaction.set("key", "value").get("key");
// Execute the transaction
Object[] result = client.exec(transaction).get();
System.out.println(Arrays.toString(result)); // Output: [OK, "value"]
EVAL
The EVAL
command executes Lua scripts in Valkey.
- In Jedis, Lua scripts are executed using
eval()
. - In Glide, Lua scripts are executed via
invokeScript()
using aScript
object.
TheScript
class wraps the Lua script, and the second parameter (boolean binaryOutput
) controls the output format:
false
returns a String, whiletrue
returns binary data.
Jedis
String script = "return 'Hello, Lua!'";
Object result = jedis.eval(script);
System.out.println(result); // Output: Hello, Lua!
Glide
Script luaScript = new Script("return 'Hello, Lua!'", false);
String result = (String) glideClient.invokeScript(luaScript).get();
System.out.println(result); // Output: Hello, Lua!
EVALSHA
The EVALSHA
command is similar to EVAL
, but instead of passing the Lua script directly, it uses a SHA1 hash of a pre-loaded script.
- In Jedis, the script must be preloaded using
scriptLoad()
. - In Glide,
invokeScript()
is used withScriptOptions
.
Jedis
String script = "return redis.call('set', KEYS[1], ARGV[1]);";
String sha1 = jedis.scriptLoad(script);
Object result = jedis.evalsha(sha1, Arrays.asList("myKey"), Arrays.asList("10"));
System.out.println(result); // Output: OK
Glide
String script = "return server.call('set', KEYS[1], ARGV[1]);";
Script luaScript = new Script(script, false);
ScriptOptions scriptOptions = ScriptOptions.builder().key("myKey").arg("10").build();
String result = (String) glideClient.invokeScript(luaScript, scriptOptions).get();
System.out.println(result); // Output: OK
SCAN
The SCAN
command iterates through keys in the Valkey database without blocking the server.
- Both Jedis and Glide support scanning with or without
ScanParams
. - Glide supports cluster mode scanning to scan the entire cluster. For more.
Jedis
String cursor = ScanParams.SCAN_POINTER_START;
ScanResult<String> scanResult;
do {
scanResult = jedis.scan(cursor);
cursor = scanResult.getCursor();
List<String> keys = scanResult.getResult();
String keyList = String.join(", ", keys);
System.out.println("\nSCAN iteration: " + keyList);
} while (!cursor.equals(ScanParams.SCAN_POINTER_START));
Glide
String cursor = "0";
Object[] result;
do {
result = glideClient.scan(cursor).get();
cursor = result[0].toString();
Object[] stringResults = (Object[]) result[1];
String keyList = Arrays.stream(stringResults)
.map(obj -> (String) obj)
.collect(Collectors.joining(", "));
System.out.println("\nSCAN iteration: " + keyList);
} while (!cursor.equals("0"));
Authentication (AUTH)
The AUTH
command is used to authenticate a Valkey connection with a password.
- In Jedis, authentication is done via
auth()
. - In Glide, authentication is handled using
updateConnectionPassword()
.
Jedis
// Returns OK if the password is correct, otherwise returns an error
String res = jedis.auth("111");
Glide
// Returns OK if the password is correct, otherwise returns an error
glideClient.updateConnectionPassword("newPassword", true).get();
Note: Setting immediateAuth = false
allows the client to use the new password for future connections without re-authentication.
INFO
The INFO
command retrieves detailed information about the Valkey server, including memory usage, connected clients, and database statistics.
- Both Jedis and Glide support this command in the same way.
Jedis
String info = jedis.info();
Glide
String info = glideClient.info().get();
Change Database (SELECT)
The SELECT
command switches between Valkey databases.
- Both Jedis and Glide support this in the same way.
Jedis
String res = jedis.select(1); // Output: OK
Glide
String res = glideClient.select(1).get(); // Output: OK
Here's a clearer and more polished version:
The customCommand
function lets you execute any Valkey command as a raw list of arguments, without input validation. It's a flexible option when the standard Glide API doesn't cover a specific command.
You can use it whenever you're unsure of the dedicated method or want to quickly run a command directly.
Example:
String[] command = { "SET", "key", "value" };
glideClient.customCommand(command).get();
This sends the raw SET key value
command to Valkey.
Routing allows you to manually control which node(s) in the cluster a command is sent to.
Note: Routing key-based commands is generally not necessary or recommended, as Glide already routes them automatically based on the key’s hash slot.
There are two types of routing:
- Single-node routing: targets one specific node (e.g., a random node, replica, or node by address).
- Multi-node routing: broadcasts the command to multiple nodes (e.g., all nodes or all primaries).
Available Routing Options:
// Multi-Node Routes
import static glide.api.models.configuration.RequestRoutingConfiguration.SimpleMultiNodeRoute.ALL_NODES;
import static glide.api.models.configuration.RequestRoutingConfiguration.SimpleMultiNodeRoute.ALL_PRIMARIES;
// Single-Node Routes
import static glide.api.models.configuration.RequestRoutingConfiguration.SimpleSingleNodeRoute.RANDOM;
// Slot-based Routing
import glide.api.models.configuration.RequestRoutingConfiguration.SlotIdRoute; // by slot number + SlotType (PRIMARY / REPLICA)
import glide.api.models.configuration.RequestRoutingConfiguration.SlotKeyRoute; // by key + SlotType
import glide.api.models.configuration.RequestRoutingConfiguration.ByAddressRoute; // by host + port
// SlotType Enum
import static glide.api.models.configuration.RequestRoutingConfiguration.SlotType.PRIMARY;
import static glide.api.models.configuration.RequestRoutingConfiguration.SlotType.REPLICA;
Reading Routing Results
The way you access the response depends on the routing type you used:
String message = "GLIDE";
// Route to a single random node
String singlePayload = clusterClient.echo(message, RANDOM).get().getSingleValue();
assertEquals(message, singlePayload);
// Route to all nodes
Map<String, String> multiPayload = clusterClient.echo(message, ALL_NODES).get().getMultiValue();
multiPayload.forEach((key, value) -> assertEquals(message, value));