diff --git a/content/develop/use-cases/feature-store/java-jedis/BuildFeatures.java b/content/develop/use-cases/feature-store/java-jedis/BuildFeatures.java index 670a07cfae..8109ff3d10 100644 --- a/content/develop/use-cases/feature-store/java-jedis/BuildFeatures.java +++ b/content/develop/use-cases/feature-store/java-jedis/BuildFeatures.java @@ -3,7 +3,7 @@ import java.util.Map; import java.util.Random; -import redis.clients.jedis.JedisPool; +import redis.clients.jedis.RedisClient; /** * Synthesize a small batch of users with realistic-looking features @@ -78,8 +78,8 @@ public static void main(String[] args) { } } - try (JedisPool pool = new JedisPool(redisHost, redisPort)) { - FeatureStore store = new FeatureStore(pool, keyPrefix, ttlSeconds, + try (RedisClient jedis = RedisClient.create(redisHost, redisPort)) { + FeatureStore store = new FeatureStore(jedis, keyPrefix, ttlSeconds, FeatureStore.DEFAULT_STREAMING_TTL_SECONDS); Map> rows = synthesizeUsers(count, seed); int loaded = store.bulkLoad(rows, ttlSeconds); diff --git a/content/develop/use-cases/feature-store/java-jedis/DemoServer.java b/content/develop/use-cases/feature-store/java-jedis/DemoServer.java index a8939a60eb..8486229f9c 100644 --- a/content/develop/use-cases/feature-store/java-jedis/DemoServer.java +++ b/content/develop/use-cases/feature-store/java-jedis/DemoServer.java @@ -16,8 +16,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantLock; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.ConnectionPoolConfig; +import redis.clients.jedis.RedisClient; /** * Redis feature-store demo server (Jedis + JDK HttpServer). @@ -35,7 +35,7 @@ public class DemoServer { private static FeatureStore store; private static StreamingWorker worker; private static FeatureStoreDemo demo; - private static JedisPool jedisPool; + private static RedisClient jedis; public static void main(String[] args) throws Exception { String host = "127.0.0.1"; @@ -77,13 +77,16 @@ public static void main(String[] args) throws Exception { } } - JedisPoolConfig poolCfg = new JedisPoolConfig(); + ConnectionPoolConfig poolCfg = new ConnectionPoolConfig(); poolCfg.setMaxTotal(64); poolCfg.setMaxIdle(32); poolCfg.setMinIdle(4); - jedisPool = new JedisPool(poolCfg, redisHost, redisPort); + jedis = RedisClient.builder() + .hostAndPort(redisHost, redisPort) + .poolConfig(poolCfg) + .build(); - store = new FeatureStore(jedisPool, keyPrefix, + store = new FeatureStore(jedis, keyPrefix, batchTtlSeconds, streamingTtlSeconds); worker = new StreamingWorker(store, 1000L, usersPerTick, 1337L); demo = new FeatureStoreDemo(store, worker, 42L); @@ -120,7 +123,7 @@ public static void main(String[] args) throws Exception { System.out.println("\nShutting down..."); worker.stop(); server.stop(0); - jedisPool.close(); + jedis.close(); })); Thread.currentThread().join(); diff --git a/content/develop/use-cases/feature-store/java-jedis/FeatureStore.java b/content/develop/use-cases/feature-store/java-jedis/FeatureStore.java index 019a1e1c5e..32cbef86b4 100644 --- a/content/develop/use-cases/feature-store/java-jedis/FeatureStore.java +++ b/content/develop/use-cases/feature-store/java-jedis/FeatureStore.java @@ -5,9 +5,8 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisPool; import redis.clients.jedis.Pipeline; +import redis.clients.jedis.RedisClient; import redis.clients.jedis.Response; /** @@ -67,7 +66,7 @@ public class FeatureStore { public static final long DEFAULT_STREAMING_TTL_SECONDS = 5L * 60L; public static final String DEFAULT_KEY_PREFIX = "fs:user:"; - private final JedisPool pool; + private final RedisClient jedis; private final String keyPrefix; private final long batchTtlSeconds; private final long streamingTtlSeconds; @@ -77,15 +76,15 @@ public class FeatureStore { private final AtomicLong readsTotal = new AtomicLong(); private final AtomicLong readFieldsTotal = new AtomicLong(); - public FeatureStore(JedisPool pool) { - this(pool, DEFAULT_KEY_PREFIX, + public FeatureStore(RedisClient jedis) { + this(jedis, DEFAULT_KEY_PREFIX, DEFAULT_BATCH_TTL_SECONDS, DEFAULT_STREAMING_TTL_SECONDS); } - public FeatureStore(JedisPool pool, String keyPrefix, + public FeatureStore(RedisClient jedis, String keyPrefix, long batchTtlSeconds, long streamingTtlSeconds) { - this.pool = pool; + this.jedis = jedis; this.keyPrefix = keyPrefix; this.batchTtlSeconds = batchTtlSeconds; this.streamingTtlSeconds = streamingTtlSeconds; @@ -115,8 +114,7 @@ public String keyFor(String entityId) { */ public int bulkLoad(Map> rows, long ttlSeconds) { if (rows.isEmpty()) return 0; - try (Jedis jedis = pool.getResource()) { - Pipeline pipe = jedis.pipelined(); + try (Pipeline pipe = jedis.pipelined()) { for (Map.Entry> e : rows.entrySet()) { String key = keyFor(e.getKey()); Map encoded = encode(e.getValue()); @@ -139,9 +137,7 @@ public int bulkLoad(Map> rows) { * pipelines flow through {@link #bulkLoad}. */ public void updateBatchFeature(String entityId, String field, Object value) { - try (Jedis jedis = pool.getResource()) { - jedis.hset(keyFor(entityId), field, encodeValue(value)); - } + jedis.hset(keyFor(entityId), field, encodeValue(value)); batchWritesTotal.incrementAndGet(); } @@ -180,13 +176,13 @@ public void updateStreaming(String entityId, Map fields, long tt String[] names = encoded.keySet().toArray(new String[0]); List expireCodes; - try (Jedis jedis = pool.getResource()) { - Pipeline pipe = jedis.pipelined(); + Response> expireResp; + try (Pipeline pipe = jedis.pipelined()) { pipe.hset(key, encoded); - Response> expireResp = pipe.hexpire(key, ttlSeconds, names); + expireResp = pipe.hexpire(key, ttlSeconds, names); pipe.sync(); - expireCodes = expireResp.get(); } + expireCodes = expireResp.get(); for (Long code : expireCodes) { if (code == null || code != 1L) { throw new IllegalStateException( @@ -215,19 +211,15 @@ public Map getFeatures(String entityId, List fieldNames) String key = keyFor(entityId); Map out = new LinkedHashMap<>(); if (fieldNames == null) { - try (Jedis jedis = pool.getResource()) { - Map all = jedis.hgetAll(key); - if (all != null) out.putAll(all); - } + Map all = jedis.hgetAll(key); + if (all != null) out.putAll(all); readsTotal.incrementAndGet(); readFieldsTotal.addAndGet(out.size()); return out; } if (fieldNames.isEmpty()) return out; List values; - try (Jedis jedis = pool.getResource()) { - values = jedis.hmget(key, fieldNames.toArray(new String[0])); - } + values = jedis.hmget(key, fieldNames.toArray(new String[0])); for (int i = 0; i < fieldNames.size(); i++) { String v = values.get(i); if (v != null) out.put(fieldNames.get(i), v); @@ -253,8 +245,7 @@ public Map> batchGetFeatures( String[] names = fieldNames.toArray(new String[0]); Map> out = new LinkedHashMap<>(); List>> responses = new ArrayList<>(entityIds.size()); - try (Jedis jedis = pool.getResource()) { - Pipeline pipe = jedis.pipelined(); + try (Pipeline pipe = jedis.pipelined()) { for (String id : entityIds) { responses.add(pipe.hmget(keyFor(id), names)); } @@ -287,9 +278,7 @@ public Map> batchGetFeatures( * key-level TTL is set, {@code -2} if the key doesn't exist. */ public long keyTtlSeconds(String entityId) { - try (Jedis jedis = pool.getResource()) { - return jedis.ttl(keyFor(entityId)); - } + return jedis.ttl(keyFor(entityId)); } /** @@ -302,9 +291,7 @@ public long keyTtlSeconds(String entityId) { public Map fieldTtlsSeconds(String entityId, List fieldNames) { if (fieldNames.isEmpty()) return Collections.emptyMap(); List codes; - try (Jedis jedis = pool.getResource()) { - codes = jedis.httl(keyFor(entityId), fieldNames.toArray(new String[0])); - } + codes = jedis.httl(keyFor(entityId), fieldNames.toArray(new String[0])); Map out = new LinkedHashMap<>(); for (int i = 0; i < fieldNames.size(); i++) { // HTTL on a missing key returns a flat list of -2s; jedis @@ -329,24 +316,22 @@ public List listEntityIds(int limit) { List ids = new ArrayList<>(); String pattern = keyPrefix + "*"; String cursor = "0"; - try (Jedis jedis = pool.getResource()) { - do { - redis.clients.jedis.params.ScanParams params = new redis.clients.jedis.params.ScanParams() - .match(pattern) - .count(200); - redis.clients.jedis.resps.ScanResult sr = jedis.scan(cursor, params); - for (String k : sr.getResult()) { - if (k.length() > keyPrefix.length()) { - ids.add(k.substring(keyPrefix.length())); - if (ids.size() >= limit) { - Collections.sort(ids); - return ids; - } + do { + redis.clients.jedis.params.ScanParams params = new redis.clients.jedis.params.ScanParams() + .match(pattern) + .count(200); + redis.clients.jedis.resps.ScanResult sr = jedis.scan(cursor, params); + for (String k : sr.getResult()) { + if (k.length() > keyPrefix.length()) { + ids.add(k.substring(keyPrefix.length())); + if (ids.size() >= limit) { + Collections.sort(ids); + return ids; } } - cursor = sr.getCursor(); - } while (!"0".equals(cursor)); - } + } + cursor = sr.getCursor(); + } while (!"0".equals(cursor)); Collections.sort(ids); return ids; } @@ -360,23 +345,19 @@ public long countEntities() { long count = 0; String pattern = keyPrefix + "*"; String cursor = "0"; - try (Jedis jedis = pool.getResource()) { - do { - redis.clients.jedis.params.ScanParams params = new redis.clients.jedis.params.ScanParams() - .match(pattern) - .count(500); - redis.clients.jedis.resps.ScanResult sr = jedis.scan(cursor, params); - count += sr.getResult().size(); - cursor = sr.getCursor(); - } while (!"0".equals(cursor)); - } + do { + redis.clients.jedis.params.ScanParams params = new redis.clients.jedis.params.ScanParams() + .match(pattern) + .count(500); + redis.clients.jedis.resps.ScanResult sr = jedis.scan(cursor, params); + count += sr.getResult().size(); + cursor = sr.getCursor(); + } while (!"0".equals(cursor)); return count; } public long deleteEntity(String entityId) { - try (Jedis jedis = pool.getResource()) { - return jedis.del(keyFor(entityId)); - } + return jedis.del(keyFor(entityId)); } /** @@ -389,19 +370,17 @@ public long reset() { long deleted = 0; String pattern = keyPrefix + "*"; String cursor = "0"; - try (Jedis jedis = pool.getResource()) { - do { - redis.clients.jedis.params.ScanParams params = new redis.clients.jedis.params.ScanParams() - .match(pattern) - .count(500); - redis.clients.jedis.resps.ScanResult sr = jedis.scan(cursor, params); - List batch = sr.getResult(); - if (!batch.isEmpty()) { - deleted += jedis.del(batch.toArray(new String[0])); - } - cursor = sr.getCursor(); - } while (!"0".equals(cursor)); - } + do { + redis.clients.jedis.params.ScanParams params = new redis.clients.jedis.params.ScanParams() + .match(pattern) + .count(500); + redis.clients.jedis.resps.ScanResult sr = jedis.scan(cursor, params); + List batch = sr.getResult(); + if (!batch.isEmpty()) { + deleted += jedis.del(batch.toArray(new String[0])); + } + cursor = sr.getCursor(); + } while (!"0".equals(cursor)); return deleted; } diff --git a/content/develop/use-cases/feature-store/java-jedis/_index.md b/content/develop/use-cases/feature-store/java-jedis/_index.md index b1a5894629..9db6763da4 100644 --- a/content/develop/use-cases/feature-store/java-jedis/_index.md +++ b/content/develop/use-cases/feature-store/java-jedis/_index.md @@ -126,13 +126,16 @@ The `FeatureStore` class wraps the read/write paths ([source](https://github.com/redis/docs/blob/main/content/develop/use-cases/feature-store/java-jedis/FeatureStore.java)): ```java -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.ConnectionPoolConfig; +import redis.clients.jedis.RedisClient; -JedisPoolConfig cfg = new JedisPoolConfig(); +ConnectionPoolConfig cfg = new ConnectionPoolConfig(); cfg.setMaxTotal(64); -JedisPool pool = new JedisPool(cfg, "localhost", 6379); -FeatureStore store = new FeatureStore(pool, +RedisClient jedis = RedisClient.builder() + .hostAndPort("localhost", 6379) + .poolConfig(cfg) + .build(); +FeatureStore store = new FeatureStore(jedis, "fs:user:", 24L * 60L * 60L, // whole-entity TTL aligned with the daily batch cycle 5L * 60L // per-field TTL on each streaming feature @@ -220,8 +223,7 @@ server side but the client only pays one RTT. ```java public int bulkLoad(Map> rows, long ttlSeconds) { if (rows.isEmpty()) return 0; - try (Jedis jedis = pool.getResource()) { - Pipeline pipe = jedis.pipelined(); + try (Pipeline pipe = jedis.pipelined()) { for (Map.Entry> e : rows.entrySet()) { String key = keyFor(e.getKey()); Map encoded = encode(e.getValue()); @@ -265,13 +267,13 @@ public void updateStreaming(String entityId, Map fields, long tt String[] names = encoded.keySet().toArray(new String[0]); List expireCodes; - try (Jedis jedis = pool.getResource()) { - Pipeline pipe = jedis.pipelined(); + Response> expireResp; + try (Pipeline pipe = jedis.pipelined()) { pipe.hset(key, encoded); - Response> expireResp = pipe.hexpire(key, ttlSeconds, names); + expireResp = pipe.hexpire(key, ttlSeconds, names); pipe.sync(); - expireCodes = expireResp.get(); } + expireCodes = expireResp.get(); for (Long code : expireCodes) { if (code == null || code != 1L) { throw new IllegalStateException( @@ -309,7 +311,7 @@ in the model itself. > **HEXPIRE requires Redis 7.4 or later.** `HEXPIRE` and the field-level TTL > commands (`HTTL`, `HPERSIST`, `HEXPIREAT`, `HPEXPIRE`, `HPEXPIREAT`, > `HPTTL`, `HEXPIRETIME`, `HPEXPIRETIME`) were added in Redis 7.4. Jedis 5.2 -> was the first release with the bindings; the demo's `pom.xml` pins 6.2. +> was the first release with the bindings; the demo's `pom.xml` pins 8.0.2. > On older Redis builds you would have to put streaming features on their > own keys (one key per feature, or one key per feature group) and set a > key-level `EXPIRE` instead — at the cost of giving up the single-`HMGET` @@ -324,17 +326,13 @@ public Map getFeatures(String entityId, List fieldNames) String key = keyFor(entityId); Map out = new LinkedHashMap<>(); if (fieldNames == null) { - try (Jedis jedis = pool.getResource()) { - Map all = jedis.hgetAll(key); - if (all != null) out.putAll(all); - } + Map all = jedis.hgetAll(key); + if (all != null) out.putAll(all); return out; } if (fieldNames.isEmpty()) return out; List values; - try (Jedis jedis = pool.getResource()) { - values = jedis.hmget(key, fieldNames.toArray(new String[0])); - } + values = jedis.hmget(key, fieldNames.toArray(new String[0])); for (int i = 0; i < fieldNames.size(); i++) { String v = values.get(i); if (v != null) out.put(fieldNames.get(i), v); @@ -368,8 +366,7 @@ public Map> batchGetFeatures( } String[] names = fieldNames.toArray(new String[0]); List>> responses = new ArrayList<>(entityIds.size()); - try (Jedis jedis = pool.getResource()) { - Pipeline pipe = jedis.pipelined(); + try (Pipeline pipe = jedis.pipelined()) { for (String id : entityIds) { responses.add(pipe.hmget(keyFor(id), names)); } @@ -513,8 +510,8 @@ pool. The HTML page lets you: read time. The server holds one `FeatureStore` and one `StreamingWorker` for the -lifetime of the process, plus a `JedisPool` that all handlers borrow -connections from. Endpoints: +lifetime of the process, plus a `RedisClient` whose connection pool all +handlers borrow from. Endpoints: | Endpoint | What it does | |---------------------------|-------------------------------------------------------------------------------------| @@ -533,9 +530,9 @@ connections from. Endpoints: demo relies on per-field TTL for the mixed-staleness story. * **Java 17 or later.** The demo uses switch expressions with arrow labels (`case "..." -> ...`), records, and text blocks. -* **Jedis 5.2 or later.** The demo's `pom.xml` pins - `redis.clients:jedis:6.2.0`. Field-level TTL bindings (`hexpire`, `httl`, - `hpersist`) ship from Jedis 5.2. +* **Jedis 8.0 or later.** The demo uses `RedisClient`, and its `pom.xml` + pins `redis.clients:jedis:8.0.2`. Field-level TTL bindings (`hexpire`, + `httl`, `hpersist`) ship from Jedis 5.2. If your Redis server is running elsewhere, start the demo with `--redis-host` and `--redis-port`. @@ -607,7 +604,7 @@ is `fs:user:`. Pass `--no-reset` to keep existing data across restarts, or The guidance below focuses on the production concerns that are specific to running a feature store on Redis. For the generic Jedis production checklist -— `JedisPool` sizing, AUTH/ACL, retry policy, sentinel/cluster failover — +— connection pool sizing, AUTH/ACL, retry policy, sentinel/cluster failover — see the [Jedis production usage guide](/content/develop/clients/jedis/produsage.md). For TLS specifically, follow the @@ -679,11 +676,11 @@ The exception is debugging and feature-set discovery, where you genuinely want the full hash. The demo's "Inspect" button uses `hgetAll` for exactly this reason. -### Size the JedisPool for the request shape +### Size the connection pool for the request shape Every `FeatureStore` helper method borrows a connection from the -`JedisPool` for the duration of one Redis call (or one `Pipeline.sync()`) -and returns it via the try-with-resources block. One HTTP handler can +`RedisClient` pool for the duration of one Redis call (or one pipeline, +until try-with-resources closes it) and returns it afterwards. One HTTP handler can therefore borrow several connections sequentially — `/read`, for example, makes one `hmget` call, one `httl` call, and one `ttl` call, each of which is its own borrow. diff --git a/content/develop/use-cases/feature-store/java-jedis/pom.xml b/content/develop/use-cases/feature-store/java-jedis/pom.xml index fbed81d6dd..6431c94e29 100644 --- a/content/develop/use-cases/feature-store/java-jedis/pom.xml +++ b/content/develop/use-cases/feature-store/java-jedis/pom.xml @@ -30,11 +30,11 @@ + (hexpire / httl / hpersist); the demo pins 8.0.2. --> redis.clients jedis - 6.2.0 + 8.0.2 diff --git a/content/develop/use-cases/memory-layer/java-jedis/_index.md b/content/develop/use-cases/memory-layer/java-jedis/_index.md index d85ccdbe50..9f56c8ef71 100644 --- a/content/develop/use-cases/memory-layer/java-jedis/_index.md +++ b/content/develop/use-cases/memory-layer/java-jedis/_index.md @@ -57,9 +57,9 @@ The embedding is computed once and reused for steps 3 and 4 — there's no point import com.redis.agentmem.AgentSession; import com.redis.agentmem.SessionState; import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; -JedisPooled jedis = new JedisPooled(new HostAndPort("localhost", 6379)); +RedisClient jedis = RedisClient.create(new HostAndPort("localhost", 6379)); AgentSession session = new AgentSession(jedis, "agent:session:", 3600, 20); String threadId = session.newThreadId(); diff --git a/content/develop/use-cases/memory-layer/java-jedis/pom.xml b/content/develop/use-cases/memory-layer/java-jedis/pom.xml index a25b43e75e..7834142d49 100644 --- a/content/develop/use-cases/memory-layer/java-jedis/pom.xml +++ b/content/develop/use-cases/memory-layer/java-jedis/pom.xml @@ -21,7 +21,7 @@ 17 17 UTF-8 - 5.2.0 + 8.0.2 0.33.0 20240303 diff --git a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentEventLog.java b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentEventLog.java index 832c8a0758..0c49b63bcc 100644 --- a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentEventLog.java +++ b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentEventLog.java @@ -1,6 +1,6 @@ package com.redis.agentmem; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import redis.clients.jedis.StreamEntryID; import redis.clients.jedis.params.XAddParams; import redis.clients.jedis.resps.StreamEntry; @@ -35,11 +35,11 @@ public final class AgentEventLog { /** Approximate cap on stream length. */ public static final long DEFAULT_MAX_LEN = 1000L; - private final JedisPooled jedis; + private final RedisClient jedis; private final String keyPrefix; private final long maxLen; - public AgentEventLog(JedisPooled jedis, String keyPrefix, long maxLen) { + public AgentEventLog(RedisClient jedis, String keyPrefix, long maxLen) { this.jedis = jedis; this.keyPrefix = keyPrefix; this.maxLen = maxLen > 0 ? maxLen : DEFAULT_MAX_LEN; diff --git a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentSession.java b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentSession.java index f05bfa0c69..47f7206fa2 100644 --- a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentSession.java +++ b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/AgentSession.java @@ -4,7 +4,7 @@ import org.json.JSONException; import org.json.JSONObject; import redis.clients.jedis.AbstractTransaction; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import java.util.ArrayList; import java.util.HashMap; @@ -38,13 +38,13 @@ public final class AgentSession { /** Default rolling-window size. */ public static final int DEFAULT_MAX_TURNS = 20; - private final JedisPooled jedis; + private final RedisClient jedis; private final String keyPrefix; private final long defaultTtlSeconds; private final int maxTurns; public AgentSession( - JedisPooled jedis, + RedisClient jedis, String keyPrefix, long defaultTtlSeconds, int maxTurns) { diff --git a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/DemoServer.java b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/DemoServer.java index 086b7cfa0b..3cacb1556b 100644 --- a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/DemoServer.java +++ b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/DemoServer.java @@ -8,7 +8,7 @@ import redis.clients.jedis.ConnectionPoolConfig; import redis.clients.jedis.DefaultJedisClientConfig; import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import java.io.IOException; import java.io.InputStream; @@ -61,13 +61,14 @@ public static void main(String[] argv) throws Exception { poolConfig.setMaxTotal(16); poolConfig.setMaxIdle(4); poolConfig.setMinIdle(1); - JedisPooled jedis = new JedisPooled( - poolConfig, - new HostAndPort(args.redisHost, args.redisPort), - DefaultJedisClientConfig.builder() + RedisClient jedis = RedisClient.builder() + .hostAndPort(new HostAndPort(args.redisHost, args.redisPort)) + .poolConfig(poolConfig) + .clientConfig(DefaultJedisClientConfig.builder() .socketTimeoutMillis(2000) .connectionTimeoutMillis(2000) - .build()); + .build()) + .build(); try { jedis.ping(); } catch (Exception ex) { diff --git a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/LongTermMemory.java b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/LongTermMemory.java index d9c3707a5c..539d445e34 100644 --- a/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/LongTermMemory.java +++ b/content/develop/use-cases/memory-layer/java-jedis/src/main/java/com/redis/agentmem/LongTermMemory.java @@ -2,7 +2,7 @@ import org.json.JSONObject; import redis.clients.jedis.AbstractTransaction; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.json.Path2; import redis.clients.jedis.search.Document; @@ -97,7 +97,7 @@ public static Map defaultTtlByKind() { */ private static final String TAG_SPECIAL = "\\,.<>{}[]\"':;!@#$%^&*()-+=~| "; - private final JedisPooled jedis; + private final RedisClient jedis; private final String indexName; private final String keyPrefix; private final int vectorDim; @@ -106,7 +106,7 @@ public static Map defaultTtlByKind() { private final Map ttlByKind; public LongTermMemory( - JedisPooled jedis, + RedisClient jedis, String indexName, String keyPrefix, int vectorDim, diff --git a/content/develop/use-cases/recommendation-engine/java-jedis/DemoServer.java b/content/develop/use-cases/recommendation-engine/java-jedis/DemoServer.java index bd529b54f3..28a3f8d9bd 100644 --- a/content/develop/use-cases/recommendation-engine/java-jedis/DemoServer.java +++ b/content/develop/use-cases/recommendation-engine/java-jedis/DemoServer.java @@ -24,7 +24,7 @@ import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisClientConfig; import redis.clients.jedis.DefaultJedisClientConfig; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import redis.clients.jedis.ConnectionPoolConfig; /** @@ -49,7 +49,7 @@ public class DemoServer { private static final String DEMO_USER_ID = "demo"; - private static JedisPooled jedisClient; + private static RedisClient jedisClient; private static Recommender recommender; private static LocalEmbedder embedder; private static DemoState state; @@ -94,8 +94,11 @@ public static void main(String[] args) throws Exception { poolConfig.setMaxTotal(32); poolConfig.setMaxIdle(16); JedisClientConfig clientConfig = DefaultJedisClientConfig.builder().build(); - jedisClient = new JedisPooled( - new HostAndPort(redisHost, redisPort), clientConfig, poolConfig); + jedisClient = RedisClient.builder() + .hostAndPort(new HostAndPort(redisHost, redisPort)) + .clientConfig(clientConfig) + .poolConfig(poolConfig) + .build(); jedisClient.ping(); } catch (Exception exc) { System.err.printf("Failed to connect to Redis at %s:%d: %s%n", diff --git a/content/develop/use-cases/recommendation-engine/java-jedis/Recommender.java b/content/develop/use-cases/recommendation-engine/java-jedis/Recommender.java index c7eaf65cc2..6617a16b86 100644 --- a/content/develop/use-cases/recommendation-engine/java-jedis/Recommender.java +++ b/content/develop/use-cases/recommendation-engine/java-jedis/Recommender.java @@ -10,7 +10,7 @@ import java.util.TreeSet; import redis.clients.jedis.AbstractPipeline; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import redis.clients.jedis.Response; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.search.Document; @@ -72,18 +72,18 @@ public class Recommender { public static final String DEFAULT_KEY_PREFIX = "product:"; public static final String DEFAULT_USER_KEY_PREFIX = "user:"; - private final JedisPooled client; + private final RedisClient client; private final String indexName; private final String keyPrefix; private final String userKeyPrefix; private final int vectorDim; - public Recommender(JedisPooled client) { + public Recommender(RedisClient client) { this(client, DEFAULT_INDEX_NAME, DEFAULT_KEY_PREFIX, DEFAULT_USER_KEY_PREFIX, VECTOR_DIM_DEFAULT); } - public Recommender(JedisPooled client, String indexName, String keyPrefix, + public Recommender(RedisClient client, String indexName, String keyPrefix, String userKeyPrefix, int vectorDim) { if (client == null) { throw new IllegalArgumentException("client is required"); diff --git a/content/develop/use-cases/recommendation-engine/java-jedis/_index.md b/content/develop/use-cases/recommendation-engine/java-jedis/_index.md index dcc1da5116..aab8b7b5d8 100644 --- a/content/develop/use-cases/recommendation-engine/java-jedis/_index.md +++ b/content/develop/use-cases/recommendation-engine/java-jedis/_index.md @@ -59,11 +59,11 @@ The `Recommender` class wraps the Redis Search index and the retrieval flow ([source](https://github.com/redis/docs/blob/main/content/develop/use-cases/recommendation-engine/java-jedis/Recommender.java)): ```java -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; -// JedisPooled is a pool-backed UnifiedJedis: it exposes both the +// RedisClient is a pool-backed client: it exposes both the // FT.* search commands and a pipelined() API in one client. -JedisPooled jedis = new JedisPooled("localhost", 6379); +RedisClient jedis = RedisClient.create("localhost", 6379); Recommender recommender = new Recommender(jedis, "recommend:idx", "product:", "user:", 384); @@ -166,7 +166,7 @@ FT.SEARCH recommend:idx When there's no filter, the pre-filter clause is just `(*)`. `vector_score` is the cosine *distance* (0 means identical, 2 means opposite), so the result is sorted ascending and the top row is the closest candidate to the query. -The Jedis equivalent uses `JedisPooled.ftSearch(String, Query)` with the binary parameter wired through `Query.addParam("vec", floatsToBytes(vec))`: +The Jedis equivalent uses `RedisClient.ftSearch(String, Query)` with the binary parameter wired through `Query.addParam("vec", floatsToBytes(vec))`: ```java String knn = filterClause + "=>[KNN " + k + " @embedding $vec AS vector_score]"; diff --git a/content/develop/use-cases/recommendation-engine/java-jedis/pom.xml b/content/develop/use-cases/recommendation-engine/java-jedis/pom.xml index 64be1b01df..a0711f110c 100644 --- a/content/develop/use-cases/recommendation-engine/java-jedis/pom.xml +++ b/content/develop/use-cases/recommendation-engine/java-jedis/pom.xml @@ -32,7 +32,7 @@ redis.clients jedis - 6.2.0 + 8.0.2 diff --git a/content/develop/use-cases/semantic-cache/java-jedis/_index.md b/content/develop/use-cases/semantic-cache/java-jedis/_index.md index 8aa335afef..dc2b26af3a 100644 --- a/content/develop/use-cases/semantic-cache/java-jedis/_index.md +++ b/content/develop/use-cases/semantic-cache/java-jedis/_index.md @@ -57,13 +57,13 @@ The `RedisSemanticCache` class wraps the Redis Search index and the lookup / wri ([source](https://github.com/redis/docs/blob/main/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/RedisSemanticCache.java)): ```java -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import com.redis.semcache.RedisSemanticCache; import com.redis.semcache.LocalEmbedder; import com.redis.semcache.LookupResult; import com.redis.semcache.CacheHit; -JedisPooled jedis = new JedisPooled("localhost", 6379); +RedisClient jedis = RedisClient.create("localhost", 6379); LocalEmbedder embedder = LocalEmbedder.create(); // sentence-transformers/all-MiniLM-L6-v2 RedisSemanticCache cache = new RedisSemanticCache( diff --git a/content/develop/use-cases/semantic-cache/java-jedis/pom.xml b/content/develop/use-cases/semantic-cache/java-jedis/pom.xml index 6f87085b1f..5c0d2c3e71 100644 --- a/content/develop/use-cases/semantic-cache/java-jedis/pom.xml +++ b/content/develop/use-cases/semantic-cache/java-jedis/pom.xml @@ -21,7 +21,7 @@ 17 17 UTF-8 - 5.2.0 + 8.0.2 0.33.0 20240303 diff --git a/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/DemoServer.java b/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/DemoServer.java index a8089e9fb0..423dbc7c9c 100644 --- a/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/DemoServer.java +++ b/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/DemoServer.java @@ -7,7 +7,7 @@ import org.json.JSONObject; import redis.clients.jedis.ConnectionPoolConfig; import redis.clients.jedis.HostAndPort; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import java.io.IOException; import java.io.InputStream; @@ -63,13 +63,14 @@ public static void main(String[] argv) throws Exception { poolConfig.setMaxTotal(16); poolConfig.setMaxIdle(4); poolConfig.setMinIdle(1); - JedisPooled jedis = new JedisPooled( - poolConfig, - new HostAndPort(args.redisHost, args.redisPort), - redis.clients.jedis.DefaultJedisClientConfig.builder() + RedisClient jedis = RedisClient.builder() + .hostAndPort(new HostAndPort(args.redisHost, args.redisPort)) + .poolConfig(poolConfig) + .clientConfig(redis.clients.jedis.DefaultJedisClientConfig.builder() .socketTimeoutMillis(2000) .connectionTimeoutMillis(2000) - .build()); + .build()) + .build(); try { jedis.ping(); } catch (Exception ex) { diff --git a/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/RedisSemanticCache.java b/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/RedisSemanticCache.java index a10bb02448..e7c1efb1a9 100644 --- a/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/RedisSemanticCache.java +++ b/content/develop/use-cases/semantic-cache/java-jedis/src/main/java/com/redis/semcache/RedisSemanticCache.java @@ -1,7 +1,7 @@ package com.redis.semcache; import redis.clients.jedis.AbstractTransaction; -import redis.clients.jedis.JedisPooled; +import redis.clients.jedis.RedisClient; import redis.clients.jedis.Response; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.search.Document; @@ -63,7 +63,7 @@ public final class RedisSemanticCache { */ private static final String TAG_SPECIAL = "\\,.<>{}[]\"':;!@#$%^&*()-+=~| "; - private final JedisPooled jedis; + private final RedisClient jedis; private final String indexName; private final String keyPrefix; private final int vectorDim; @@ -71,7 +71,7 @@ public final class RedisSemanticCache { private final long defaultTtlSeconds; public RedisSemanticCache( - JedisPooled jedis, + RedisClient jedis, String indexName, String keyPrefix, int vectorDim,