-
Notifications
You must be signed in to change notification settings - Fork 107
Migration Guide Jedis
This guide provides a comprehensive comparison of how to migrate from Jedis to Valkey Glide, with side-by-side code examples to make the transition as smooth as possible.
Add the following dependency to your pom.xml
file:
<dependency>
<groupId>io.valkey</groupId>
<artifactId>valkey-glide</artifactId>
<version>1.3.1</version>
</dependency>
In detail
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.
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"
- Jedis offers multiple constructors for different connection configurations
- Glide uses a single configuration object that comes pre-configured with best practices
Glide typically requires minimal configuration changes for:
- Timeout settings
- TLS configuration
- Read from replica settings
- User authentication (username & password)
For advanced configurations, refer to the Glide Wiki - Java.
Standalone Mode
Jedis
// Simple connection
Jedis jedis = new Jedis("localhost", 6379);
// With options
Jedis jedisWithOptions = new Jedis("localhost", 6379, 2000);
jedisWithOptions.auth("password");
jedisWithOptions.select(0);
Glide
import glide.api.GlideClient;
import glide.api.models.configuration.GlideClientConfiguration;
import glide.api.models.configuration.AdvancedGlideClientConfiguration;
import glide.api.models.configuration.NodeAddress;
import glide.api.models.configuration.ServerCredentials;
import glide.api.models.configuration.ReadFrom;
import glide.api.models.configuration.BackoffStrategy;
import glide.api.models.configuration.TlsAdvancedConfiguration;
// Simple connection
GlideClientConfiguration config = GlideClientConfiguration.builder()
.address(NodeAddress.builder()
.host("localhost")
.port(6379)
.build())
.build();
GlideClient client = GlideClient.createClient(config).get();
// With options
GlideClientConfiguration configWithOptions = GlideClientConfiguration.builder()
.address(NodeAddress.builder()
.host("localhost")
.port(6379)
.build())
.useTLS(true)
.credentials(ServerCredentials.builder()
.username("user")
.password("password")
.build())
.readFrom(ReadFrom.AZ_AFFINITY)
.requestTimeout(2000)
.reconnectStrategy(BackoffStrategy.builder()
.numOfRetries(5)
.factor(2)
.exponentBase(2)
.jitterPercent(10)
.build())
.advancedConfiguration(AdvancedGlideClientConfiguration.builder()
.connectionTimeout(5000)
.tlsAdvancedConfiguration(TlsAdvancedConfiguration.builder()
.useInsecureTLS(false)
.build())
.build())
.build();
GlideClient clientWithOptions = GlideClient.createClient(configWithOptions).get();
Cluster Mode
Jedis
// Simple cluster connection
Set<HostAndPort> jedisClusterNodes = new HashSet<>();
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7000));
jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7001));
JedisCluster cluster = new JedisCluster(jedisClusterNodes);
// With options
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(128);
poolConfig.setMaxIdle(128);
poolConfig.setMinIdle(16);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);
JedisCluster clusterWithOptions = new JedisCluster(jedisClusterNodes, 2000, 2000, 5, "password", poolConfig);
Glide
import glide.api.GlideClusterClient;
import glide.api.models.configuration.GlideClusterClientConfiguration;
import glide.api.models.configuration.AdvancedGlideClusterClientConfiguration;
import glide.api.models.configuration.NodeAddress;
import glide.api.models.configuration.ServerCredentials;
import glide.api.models.configuration.ReadFrom;
import glide.api.models.configuration.BackoffStrategy;
import glide.api.models.configuration.TlsAdvancedConfiguration;
// Simple cluster connection
GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder()
.address(NodeAddress.builder()
.host("127.0.0.1")
.port(7000)
.build())
.address(NodeAddress.builder()
.host("127.0.0.1")
.port(7001)
.build())
.build();
GlideClusterClient clusterClient = GlideClusterClient.createClient(config).get();
// With options
GlideClusterClientConfiguration configWithOptions = GlideClusterClientConfiguration.builder()
.address(NodeAddress.builder()
.host("127.0.0.1")
.port(7000)
.build())
.address(NodeAddress.builder()
.host("127.0.0.1")
.port(7001)
.build())
.useTLS(true)
.credentials(ServerCredentials.builder()
.username("user")
.password("password")
.build())
.readFrom(ReadFrom.AZ_AFFINITY)
.requestTimeout(2000)
.reconnectStrategy(BackoffStrategy.builder()
.numOfRetries(5)
.factor(2)
.exponentBase(2)
.jitterPercent(10)
.build())
.advancedConfiguration(AdvancedGlideClientConfiguration.builder()
.connectionTimeout(5000)
.tlsAdvancedConfiguration(TlsAdvancedConfiguration.builder()
.useInsecureTLS(false)
.build())
.build())
.build();
GlideClusterClient clusterClientWithOptions = GlideClusterClient.createClient(configWithOptions).get();
Constructor Parameters Comparison
The table below compares Jedis constructors with Glide configuration parameters:
Jedis Parameter | Equivalent Glide Configuration |
---|---|
host: String |
address(NodeAddress.builder().host(host).build()) |
port: int |
address(NodeAddress.builder().port(port).build()) |
timeout: int |
requestTimeout(timeout) |
password: String |
credentials(ServerCredentials.builder().password(password).build()) |
user: String |
credentials(ServerCredentials.builder().username(user).build()) |
db: int |
Use client.select(db) after connection |
ssl: boolean |
useTLS(true) |
maxAttempts: int |
connectionBackoff(ConnectionBackoffStrategy.builder().numberOfRetries(maxAttempts).build()) |
clientName: String |
clientName(String) |
readFrom: ReadFrom |
readFrom(ReadFrom.REPLICA) / readFrom(ReadFrom.PREFER_REPLICA) / readFrom(ReadFrom.AZ_AFFINITY) / readFrom(ReadFrom.AZ_AFFINITY_REPLICAS_AND_PRIMARY) Read about AZ affinity
|
lazyConnect: boolean |
Not supported yet |
Advanced configuration
Standalone Mode uses GlideClientConfiguration
and Cluster Mode uses GlideClusterClientConfiguration
, but the usage is similar:
// Standalone mode
GlideClientConfiguration config = GlideClientConfiguration.builder()
.address(NodeAddress.builder()
.host("localhost")
.port(6379)
.build())
.requestTimeout(500)
.build();
GlideClient client = GlideClient.createClient(config).get();
// Cluster mode
GlideClusterClientConfiguration clusterConfig = GlideClusterClientConfiguration.builder()
.address(NodeAddress.builder()
.host("localhost")
.port(7000)
.build())
.requestTimeout(500)
.build();
GlideClusterClient clusterClient = GlideClusterClient.createClient(clusterConfig).get();
Below is a comprehensive list of common Redis commands and how they are implemented in both Jedis and Glide.
NOTE: Glide uses asynchronous execution, so most commands return a CompletableFuture<T>
. Use .get()
to retrieve the result.
SET & GET
The SET
command stores a key-value pair in Valkey, while GET
retrieves the value associated with a key.
- Both Jedis and Glide support these commands 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
client.set("key", "value");
// Retrieve the value
String value = client.get("key").get(); // value = "value"
Note: The .get()
is required in Glide because get()
returns a CompletableFuture<String>
.
SETEX (Set with Expiry)
The SETEX
command sets a key with an expiration time in seconds.
- In Jedis, this is a dedicated function.
- In Glide, expiration is handled using an additional parameter in the
set()
command.
Jedis
jedis.setex("key", 5, "value"); // Set with 5 second expiry
Glide
client.set("key", "value", SetOptions.builder().expiry(Seconds(5L)).build()).get();
SETNX (Set if Not Exists)
The SETNX
command sets a key only if it does not already exist.
- In Jedis, this is a dedicated function that returns 1 if the key was set, 0 if the key already exists.
- In Glide, this is handled using conditional set options within the
set()
command.
Jedis
Long result = jedis.setnx("key", "value"); // Returns 1 if key was set, 0 if key exists
Glide
import glide.api.models.commands.SetOptions;
import glide.api.models.commands.ConditionalChange;
String result = client.set("key", "value", SetOptions.builder()
.conditionalSet(ConditionalChange.ONLY_IF_DOES_NOT_EXIST)
.build()).get(); // Returns "OK" if key was set, null if key exists
MSET & MGET (Multiple Set/Get)
The MSET
command sets multiple key-value pairs in a single operation, while MGET
retrieves values for multiple keys.
- In Jedis,
mset()
accepts a Map of key-value pairs. - In Glide,
mset()
also accepts a Map with key-value pairs. - For
mget()
, Jedis accepts multiple keys as separate arguments, while Glide requires an array of keys.
Jedis
// Multiple set
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
String result = jedis.mset(map); // "OK"
// Multiple get
List<String> values = jedis.mget("key1", "key2"); // ["value1", "value2"]
Glide
// Multiple set
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
client.mset(map);
// Multiple get
String[] values = client.mget(new String[]{"key1", "key2"}).get(); // ["value1", "value2"]
INCR & 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 in the same way.
- The key must contain an integer value, otherwise an error will be returned.
Jedis
jedis.set("counter", "1");
jedis.incr("counter"); // counter = 2
jedis.decr("counter"); // counter = 1
Glide
client.set("counter", "1");
client.incr("counter").get(); // counter = 2
client.decr("counter").get(); // counter = 1
INCRBY & DECRBY
The INCRBY
command increases the value of a key by a specified amount, while DECRBY
decreases it by a specified amount.
- Both Jedis and Glide support these commands in the same way.
- The key must contain an integer value, otherwise an error will be returned.
Jedis
long counter = jedis.incrBy("counter", 5); // counter: 5
counter = jedis.decrBy("counter", 2); // counter: 3
Glide
long counter = client.incrBy("counter", 5).get(); // counter: 5
counter = client.decrBy("counter", 2).get(); // counter: 3
APPEND
The APPEND
command appends a value to the end of an existing string stored at a key.
- Both Jedis and Glide support this command in the same way.
- Returns the length of the string after the append operation.
Jedis
jedis.set("greeting", "Hello");
Long length = jedis.append("greeting", " World"); // Returns length: 11
String result = jedis.get("greeting"); // "Hello World"
Glide
client.set("greeting", "Hello");
Long length = client.append("greeting", " World").get(); // Returns length: 11
String result = client.get("greeting").get(); // "Hello World"
GETRANGE & SETRANGE
The GETRANGE
command retrieves a substring from a string value stored at a key, while SETRANGE
overwrites part of a string at a key starting at a specified offset.
- Both Jedis and Glide support these commands in the same way.
- Note the camelCase method names in Glide:
getRange
andsetRange
.
Jedis
jedis.set("key", "Hello World");
String result = jedis.getrange("key", 0, 4); // "Hello"
jedis.setrange("key", 6, "Redis"); // Returns length: 11
String updated = jedis.get("key"); // "Hello Redis"
Glide
client.set("key", "Hello World");
String result = client.getRange("key", 0, 4).get(); // "Hello"
client.setRange("key", 6, "Redis").get(); // Returns length: 11
String updated = client.get("key").get(); // "Hello Redis"
DEL (Delete)
The DEL
command removes one or more keys from Valkey.
- In Jedis,
del()
accepts multiple keys as separate arguments. - In Glide,
del()
requires an array of keys.
Jedis
Long deleted = jedis.del("key1", "key2"); // 2 (number of keys deleted)
Glide
Long deleted = client.del(new String[]{"key1", "key2"}).get(); // 2 (number of keys deleted)
EXISTS
The EXISTS
command checks if one or more keys exist 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.
Jedis
boolean exists = jedis.exists("key"); // true or false for a single key
Long count = jedis.exists("key1", "key2"); // number of keys that exist
Glide
Long count = client.exists(new String[]{"key1", "key2"}).get(); // number of keys that exist
EXPIRE & TTL
The EXPIRE
command sets a time-to-live (TTL) for a key, after which it will be automatically deleted. The TTL
command returns the remaining time-to-live for a key.
- In Jedis,
expire()
returns 1 if successful, 0 if the key doesn't exist or couldn't be expired. - In Glide,
expire()
returns 1 if successful, 0 otherwise.
Jedis
Long success = jedis.expire("key", 10); // 1 (success)
Long ttl = jedis.ttl("key"); // 10 (seconds remaining)
Glide
Long success = client.expire("key", 10).get(); // 1 (success)
Long ttl = client.ttl("key").get(); // 10 (seconds remaining)
KEYS & SCAN
The KEYS
command returns all keys matching a pattern, while SCAN
iterates through keys in a more efficient way for production use.
-
KEYS
is not recommended for production use as it blocks the server until completion. -
SCAN
is the preferred method for iterating through keys in production environments.
Jedis
// KEYS (not recommended for production)
Set<String> allKeys = jedis.keys("*");
// SCAN (recommended for production)
String cursor = ScanParams.SCAN_POINTER_START;
ScanResult<String> scanResult;
do {
scanResult = jedis.scan(cursor);
cursor = scanResult.getCursor();
List<String> keys = scanResult.getResult();
if (keys.size() > 0) {
System.out.println("SCAN iteration: " + String.join(", ", keys));
}
} while (!cursor.equals(ScanParams.SCAN_POINTER_START));
Glide
// KEYS (not recommended for production)
String[] allKeys = client.keys("*").get();
// SCAN (recommended for production)
String cursor = "0";
Object[] result;
do {
result = client.scan(cursor).get();
cursor = result[0].toString();
Object[] keys = (Object[]) result[1];
if (keys.length > 0) {
String keyList = Arrays.stream(keys)
.map(obj -> (String) obj)
.collect(Collectors.joining(", "));
System.out.println("SCAN iteration: " + keyList);
}
} while (!cursor.equals("0"));
RENAME & RENAMENX
The RENAME
command renames a key, while RENAMENX
renames a key only if the new key does not already exist.
- In Jedis,
renamenx()
returns 1 if successful, 0 if the target key already exists. - In Glide,
renameNx()
returns 1 if successful, 0 if the target key already exists. - Note the camelCase method name in Glide:
renameNx
.
Jedis
jedis.set("oldkey", "value");
String result = jedis.rename("oldkey", "newkey"); // "OK"
jedis.set("key1", "value1");
Long success = jedis.renamenx("key1", "key2"); // 1 (success)
Glide
client.set("oldkey", "value");
String result = client.rename("oldkey", "newkey").get(); // "OK"
client.set("key1", "value1");
Long success = client.renameNx("key1", "key2").get(); // 1 (success)
HSET & HGET
The HSET
command sets field-value pairs in a hash stored at a key, while HGET
retrieves the value of a specific field.
- In Jedis,
hset()
accepts field-value pairs as separate arguments or as a Map. - In Glide,
hset()
accepts a Map with field-value pairs.
Jedis
// Set a single field
jedis.hset("hash", "key1", "1"); // 1 (field added)
// Set multiple fields
Map<String, String> map = new HashMap<>();
map.put("key1", "1");
map.put("key2", "2");
jedis.hset("hash", map); // 2 (fields added)
// Get a single field
String value = jedis.hget("hash", "key1"); // "1"
Glide
// Set a single field
Map<String, String> singleField = new HashMap<>();
singleField.put("key1", "1");
client.hset("hash", singleField).get(); // 1 (field added)
// Set multiple fields
Map<String, String> map = new HashMap<>();
map.put("key1", "1");
map.put("key2", "2");
client.hset("hash", map).get(); // 2 (fields added)
// Get a single field
String value = client.hget("hash", "key1").get(); // "1"
HMSET & HMGET
The HMSET
command sets multiple field-value pairs in a hash, while HMGET
retrieves values for multiple fields.
- In Jedis,
hmset()
accepts a Map of field-value pairs. - In Glide, there is no separate
hmset()
method; instead,hset()
is used for setting multiple fields. - For
hmget()
, Jedis accepts multiple fields as arguments, while Glide requires an array of fields.
Jedis
// Set multiple fields
Map<String, String> map = new HashMap<>();
map.put("key1", "1");
map.put("key2", "2");
String result = jedis.hmset("hash", map); // "OK"
// Get multiple fields
List<String> values = jedis.hmget("hash", "key1", "key2"); // ["1", "2"]
Glide
// Set multiple fields (same as hset in Glide)
Map<String, String> map = new HashMap<>();
map.put("key1", "1");
map.put("key2", "2");
client.hset("hash", map).get(); // 2 (fields added)
// Get multiple fields
String[] values = client.hmget("hash", new String[]{"key1", "key2"}).get(); // ["1", "2"]
HGETALL
The HGETALL
command retrieves all field-value pairs from a hash.
- Both Jedis and Glide support this command in the same way.
- Returns a Map with field names as keys and their values.
Jedis
Map<String, String> map = new HashMap<>();
map.put("name", "John");
map.put("age", "30");
jedis.hset("user", map);
Map<String, String> user = jedis.hgetAll("user"); // {name=John, age=30}
Glide
Map<String, String> map = new HashMap<>();
map.put("name", "John");
map.put("age", "30");
client.hset("user", map);
Map<String, String> user = client.hgetall("user").get(); // {name=John, age=30}
HDEL & HEXISTS
The HDEL
command removes one or more fields from a hash, while HEXISTS
checks if a field exists in a hash.
- In Jedis,
hdel()
accepts multiple fields as separate arguments and returns the number of fields removed. - In Glide,
hdel()
requires an array of fields. - For
hexists()
, Jedis returns true if the field exists, false if it doesn't, while Glide returns 1 or 0.
Jedis
Map<String, String> map = new HashMap<>();
map.put("key1", "1");
map.put("key2", "2");
map.put("key3", "3");
jedis.hset("hash", map);
Long deleted = jedis.hdel("hash", "key1", "key2"); // 2 (fields deleted)
Boolean exists = jedis.hexists("hash", "key3"); // true (exists)
Boolean notExists = jedis.hexists("hash", "key1"); // false (doesn't exist)
Glide
Map<String, String> map = new HashMap<>();
map.put("key1", "1");
map.put("key2", "2");
map.put("key3", "3");
client.hset("hash", map);
Long deleted = client.hdel("hash", new String[]{"key1", "key2"}).get(); // 2 (fields deleted)
Long exists = client.hexists("hash", "key3").get(); // 1 (exists)
Long notExists = client.hexists("hash", "key1").get(); // 0 (doesn't exist)
LPUSH & RPUSH
The LPUSH
command adds elements to the beginning of a list, while RPUSH
adds elements to the end of a list.
- In Jedis, these commands accept multiple elements as separate arguments.
- In Glide, they require an array of elements.
- Both return the length of the list after the operation.
Jedis
Long lengthOfList = jedis.lpush("list", "a", "b", "c"); // lengthOfList = 3
lengthOfList = jedis.rpush("list", "d", "e"); // lengthOfList = 5
Glide
Long lengthOfList = client.lpush("list", new String[]{"a", "b", "c"}).get(); // lengthOfList = 3
lengthOfList = client.rpush("list", new String[]{"d", "e"}).get(); // lengthOfList = 5
LPOP & RPOP
The LPOP
command removes and returns the first element of a list, while RPOP
removes and returns the last element.
- Both Jedis and Glide support these commands in the same way.
- Returns null if the list doesn't exist or is empty.
Jedis
jedis.rpush("list", "a", "b", "c");
String first = jedis.lpop("list"); // "a"
String last = jedis.rpop("list"); // "c"
Glide
client.rpush("list", new String[]{"a", "b", "c"});
String first = client.lpop("list").get(); // "a"
String last = client.rpop("list").get(); // "c"
LRANGE
The LRANGE
command retrieves a range of elements from a list.
- Both Jedis and Glide support this command in the same way.
- The range is specified by start and stop indices, where 0 is the first element, -1 is the last element.
Jedis
jedis.rpush("list", "a", "b", "c", "d", "e");
List<String> elements = jedis.lrange("list", 0, 2); // ["a", "b", "c"]
Glide
client.rpush("list", new String[]{"a", "b", "c", "d", "e"});
String[] elements = client.lrange("list", 0, 2).get(); // ["a", "b", "c"]
SADD & SMEMBERS
The SADD
command adds one or more members to a set, while SMEMBERS
returns all members of a set.
- In Jedis,
sadd()
accepts multiple members as separate arguments. - In Glide,
sadd()
requires an array of members. - Both return the number of members that were added to the set (excluding members that were already present).
Jedis
Long added = jedis.sadd("set", "a", "b", "c"); // 3 (members added)
Set<String> members = jedis.smembers("set"); // ["a", "b", "c"]
Glide
Long added = client.sadd("set", new String[]{"a", "b", "c"}).get(); // 3 (members added)
String[] members = client.smembers("set").get(); // ["a", "b", "c"]
SREM & SISMEMBER
The SREM
command removes one or more members from a set, while SISMEMBER
checks if a value is a member of a set.
- In Jedis,
srem()
accepts multiple members as separate arguments and returns the number of members removed. - In Glide,
srem()
requires an array of members. - For
sismember()
, Jedis returns true if the member exists, false if it doesn't, while Glide returns 1 or 0.
Jedis
jedis.sadd("set", "a", "b", "c");
Long removed = jedis.srem("set", "a", "b"); // 2 (members removed)
Boolean isMember = jedis.sismember("set", "c"); // true (is member)
Boolean notMember = jedis.sismember("set", "a"); // false (not member)
Glide
client.sadd("set", new String[]{"a", "b", "c"});
Long removed = client.srem("set", new String[]{"a", "b"}).get(); // 2 (members removed)
Long isMember = client.sismember("set", "c").get(); // 1 (is member)
Long notMember = client.sismember("set", "a").get(); // 0 (not member)
ZADD & ZRANGE
The ZADD
command adds one or more members with scores to a sorted set, while ZRANGE
retrieves members from a sorted set by index range.
- In Jedis,
zadd()
accepts score-member pairs as separate arguments. - In Glide,
zadd()
requires an array of objects with score and member properties. - For
zrange()
with scores, Jedis uses a boolean parameter, while Glide uses a string parameter.
Jedis
// Add members with scores
jedis.zadd("sortedSet", 1, "one", 2, "two", 3, "three"); // 3 (members added)
// Get range of members
List<String> members = jedis.zrange("sortedSet", 0, -1); // ["one", "two", "three"]
// With scores
Map<String, Double> withScores = jedis.zrangeWithScores("sortedSet", 0, -1)
.stream()
.collect(Collectors.toMap(
Tuple::getElement,
Tuple::getScore
)); // {one=1.0, two=2.0, three=3.0}
Glide
// Add members with scores
Object[] scoreMembers = new Object[] {
new Object[] { 1.0, "one" },
new Object[] { 2.0, "two" },
new Object[] { 3.0, "three" }
};
Long added = client.zadd("sortedSet", scoreMembers).get(); // 3 (members added)
// Get range of members
String[] members = client.zrange("sortedSet", 0, -1).get(); // ["one", "two", "three"]
// With scores
Object[] withScores = client.zrange("sortedSet", 0, -1, "WITHSCORES").get();
// ["one", "1", "two", "2", "three", "3"]
ZREM & ZSCORE
The ZREM
command removes one or more members from a sorted set, while ZSCORE
returns the score of a member in a sorted set.
- In Jedis,
zrem()
accepts multiple members as separate arguments. - In Glide,
zrem()
requires an array of members. - Both return the number of members that were removed from the sorted set.
Jedis
jedis.zadd("sortedSet", 1, "one", 2, "two", 3, "three");
Long removed = jedis.zrem("sortedSet", "one", "two"); // 2 (members removed)
Double score = jedis.zscore("sortedSet", "three"); // 3.0
Glide
Object[] scoreMembers = new Object[] {
new Object[] { 1.0, "one" },
new Object[] { 2.0, "two" },
new Object[] { 3.0, "three" }
};
client.zadd("sortedSet", scoreMembers);
Long removed = client.zrem("sortedSet", new String[]{"one", "two"}).get(); // 2 (members removed)
String score = client.zscore("sortedSet", "three").get(); // "3"
ZRANK & ZREVRANK
The ZRANK
command returns the rank (position) of a member in a sorted set, while ZREVRANK
returns the rank in reverse order.
- Both Jedis and Glide support these commands in the same way.
- Ranks are 0-based, meaning the member with the lowest score has rank 0.
-
ZREVRANK
returns the rank in descending order, where the member with the highest score has rank 0.
Jedis
jedis.zadd("sortedSet", 1, "one", 2, "two", 3, "three");
Long rank = jedis.zrank("sortedSet", "two"); // 1 (0-based index)
Long revRank = jedis.zrevrank("sortedSet", "two"); // 1 (0-based index from end)
Glide
Object[] scoreMembers = new Object[] {
new Object[] { 1.0, "one" },
new Object[] { 2.0, "two" },
new Object[] { 3.0, "three" }
};
client.zadd("sortedSet", scoreMembers);
Long rank = client.zrank("sortedSet", "two").get(); // 1 (0-based index)
Long revRank = client.zrevrank("sortedSet", "two").get(); // 1 (0-based index from end)
Transactions (MULTI / EXEC)
The MULTI
command starts a transaction block, while EXEC
executes all commands issued after MULTI.
- In Jedis, transactions are started using
jedis.multi()
. - In Glide, transactions are represented as a
Transaction
object. - The result format differs: Jedis returns a list of results, while Glide returns an array of results.
Jedis
// Start a transaction
Transaction transaction = jedis.multi();
// Add commands to the transaction
transaction.set("key", "value");
transaction.incr("counter");
transaction.get("key");
// Execute the transaction
List<Object> result = transaction.exec();
System.out.println(result); // [OK, 1, value]
Glide
import glide.api.models.Transaction;
// Initialize a transaction object
Transaction transaction = new Transaction();
// Add commands to the transaction
transaction.set("key", "value");
transaction.incr("counter");
transaction.get("key");
// Execute the transaction
Object[] result = client.exec(transaction).get();
System.out.println(Arrays.toString(result)); // [OK, 1, value]
EVAL / EVALSHA
The EVAL
command executes a Lua script on the server, while EVALSHA
executes a script cached on the server using its SHA1 hash.
- In Jedis, these commands require specifying the number of keys and passing keys and arguments separately.
- In Glide, scripts are created using the
Script
class and executed withinvokeScript()
, with keys and arguments passed in a single options object. -
Glide automatically handles script caching, so there's no need for separate
EVALSHA
handling.
Jedis
// EVAL
String script = "return 'Hello, Lua!'";
Object result = jedis.eval(script);
System.out.println(result); // Hello, Lua!
// With keys and arguments
String scriptWithArgs = "return {KEYS[1], ARGV[1]}";
Object resultWithArgs = jedis.eval(scriptWithArgs, 1, "key", "value");
System.out.println(resultWithArgs); // [key, value]
// EVALSHA
String sha1 = jedis.scriptLoad(scriptWithArgs);
Object shaResult = jedis.evalsha(sha1, 1, "key", "value");
System.out.println(shaResult); // [key, value]
Glide
import glide.api.models.Script;
import glide.api.models.ScriptOptions;
// EVAL
String script = "return 'Hello, Lua!'";
Script luaScript = new Script(script, false);
String result = (String) client.invokeScript(luaScript).get();
System.out.println(result); // Hello, Lua!
// With keys and arguments
String scriptWithArgs = "return {KEYS[1], ARGV[1]}";
Script luaScriptWithArgs = new Script(scriptWithArgs, false);
ScriptOptions options = ScriptOptions.builder()
.key("key")
.arg("value")
.build();
Object[] resultWithArgs = (Object[]) client.invokeScript(luaScriptWithArgs, options).get();
System.out.println(Arrays.toString(resultWithArgs)); // [key, value]
AUTH
The AUTH
command authenticates a client connection to the Valkey server.
- In Jedis, authentication is done using the
auth()
method. - In Glide, authentication is handled using
updateConnectionPassword()
.
Jedis
String result = jedis.auth("mypass"); // OK
Glide
String result = client.updateConnectionPassword("mypass", true).get(); // OK
Custom Commands
Both Jedis and Glide provide ways to execute custom commands.
- In Jedis, you can execute raw commands using the
sendCommand()
method. - In Glide, you can execute raw commands using
customCommand()
.
Jedis
// Execute a raw command
Object rawResult = jedis.sendCommand(Protocol.Command.SET, "key", "value");
System.out.println(rawResult); // OK
Glide
// Execute a raw command
String rawResult = client.customCommand(new String[]{"SET", "key", "value"}).get();
System.out.println(rawResult); // OK
Close / Disconnect
Properly closing connections is important to free up resources and avoid connection leaks.
- In Jedis, you need to close both standalone and cluster clients separately.
- In Glide, you only need to call
close()
on the client.
Jedis
// Close standalone connection
jedis.close();
// Close cluster connection
cluster.close();
// For connection pools
jedisPool.close();
Glide
// Close client (works for both standalone and cluster)
client.close();
Below is a comprehensive chart comparing common Redis commands between Jedis and Valkey Glide:
Command | Jedis | Valkey Glide |
---|---|---|
Connection | ||
Connect | new Jedis("host", port) |
GlideClient.createClient(config).get() |
Cluster | new JedisCluster(jedisClusterNodes) |
GlideClusterClient.createClient(config).get() |
Auth | jedis.auth("pass") |
client.updateConnectionPassword("pass", true).get() |
Select DB | jedis.select(1) |
client.select(1).get() |
Strings | ||
SET | jedis.set("key", "val") |
client.set("key", "val") |
GET | jedis.get("key") |
client.get("key").get() |
SETEX | jedis.setex("key", 10, "val") |
client.set("key", "value", SetOptions.builder().expiry(Seconds(5L)).build()).get() |
SETNX | jedis.setnx("key", "val") |
client.set("key", "val", SetOptions.builder().conditionalSet(ConditionalChange.ONLY_IF_DOES_NOT_EXIST).build()).get() |
MSET | jedis.mset(map) |
client.mset(map) |
MGET | jedis.mget("key1", "key2") |
client.mget(new String[]{"key1", "key2"}).get() |
INCR | jedis.incr("counter") |
client.incr("counter").get() |
DECR | jedis.decr("counter") |
client.decr("counter").get() |
INCRBY | jedis.incrBy("counter", 5) |
client.incrBy("counter", 5).get() |
DECRBY | jedis.decrBy("counter", 5) |
client.decrBy("counter", 5).get() |
APPEND | jedis.append("key", "val") |
client.append("key", "val").get() |
GETRANGE | jedis.getrange("key", 0, 3) |
client.getRange("key", 0, 3).get() |
SETRANGE | jedis.setrange("key", 0, "val") |
client.setRange("key", 0, "val").get() |
Keys | ||
DEL | jedis.del("key1", "key2") |
client.del(new String[]{"key1", "key2"}).get() |
EXISTS | jedis.exists("key1", "key2") |
client.exists(new String[]{"key1", "key2"}).get() |
EXPIRE | jedis.expire("key", 10) |
client.expire("key", 10).get() |
TTL | jedis.ttl("key") |
client.ttl("key").get() |
KEYS | jedis.keys("pattern") |
client.keys("pattern").get() |
SCAN | jedis.scan(cursor) |
client.scan(cursor).get() |
RENAME | jedis.rename("old", "new") |
client.rename("old", "new").get() |
RENAMENX | jedis.renamenx("old", "new") |
client.renameNx("old", "new").get() |
Hashes | ||
HSET | jedis.hset("hash", map) |
client.hset("hash", map).get() |
HGET | jedis.hget("hash", "field") |
client.hget("hash", "field").get() |
HMSET | jedis.hmset("hash", map) |
client.hset("hash", map).get() |
HMGET | jedis.hmget("hash", "f1", "f2") |
client.hmget("hash", new String[]{"f1", "f2"}).get() |
HGETALL | jedis.hgetAll("hash") |
client.hgetall("hash").get() |
HDEL | jedis.hdel("hash", "f1", "f2") |
client.hdel("hash", new String[]{"f1", "f2"}).get() |
HEXISTS | jedis.hexists("hash", "field") |
client.hexists("hash", "field").get() |
Lists | ||
LPUSH | jedis.lpush("list", "a", "b") |
client.lpush("list", new String[]{"a", "b"}).get() |
RPUSH | jedis.rpush("list", "a", "b") |
client.rpush("list", new String[]{"a", "b"}).get() |
LPOP | jedis.lpop("list") |
client.lpop("list").get() |
RPOP | jedis.rpop("list") |
client.rpop("list").get() |
LRANGE | jedis.lrange("list", 0, -1) |
client.lrange("list", 0, -1).get() |
Sets | ||
SADD | jedis.sadd("set", "a", "b") |
client.sadd("set", new String[]{"a", "b"}).get() |
SMEMBERS | jedis.smembers("set") |
client.smembers("set").get() |
SREM | jedis.srem("set", "a", "b") |
client.srem("set", new String[]{"a", "b"}).get() |
SISMEMBER | jedis.sismember("set", "a") |
client.sismember("set", "a").get() |
Sorted Sets | ||
ZADD | jedis.zadd("zset", 1, "a", 2, "b") |
client.zadd("zset", scoreMembers).get() |
ZRANGE | jedis.zrange("zset", 0, -1) |
client.zrange("zset", 0, -1).get() |
ZRANGE with scores | jedis.zrangeWithScores("zset", 0, -1) |
client.zrange("zset", 0, -1, "WITHSCORES").get() |
ZREM | jedis.zrem("zset", "a", "b") |
client.zrem("zset", new String[]{"a", "b"}).get() |
ZSCORE | jedis.zscore("zset", "a") |
client.zscore("zset", "a").get() |
ZRANK | jedis.zrank("zset", "a") |
client.zrank("zset", "a").get() |
ZREVRANK | jedis.zrevrank("zset", "a") |
client.zrevrank("zset", "a").get() |
Transactions | ||
MULTI/EXEC | jedis.multi().set("k", "v").exec() |
client.exec(new Transaction().set("k", "v")).get() |
Lua Scripts | ||
EVAL | jedis.eval(script, numKeys, keys, args) |
client.invokeScript(new Script(script), options).get() |
EVALSHA | jedis.evalsha(sha, numKeys, keys, args) |
client.invokeScript(new Script(script), options).get() |
Custom Commands | ||
Raw Command | jedis.sendCommand(Command.SET, "key", "value") |
client.customCommand(new String[]{"SET", "key", "value"}).get() |
Connection Management | ||
Close | jedis.close(); cluster.close(); |
client.close() |