Jedis

Cache LibraryJavaRedisPerformanceDistributed CacheConnection Pooling

GitHub Overview

redis/jedis

Redis Java client

Stars12,173
Watchers675
Forks3,902
Created:June 11, 2010
Language:Java
License:MIT License

Topics

javajedisredisredis-clientredis-cluster

Star History

redis/jedis Star History
Data as of: 10/22/2025, 09:55 AM

Cache Library

Jedis

Overview

Jedis is the official Redis client library for Java, supporting high-performance connection pooling, Redis Cluster, Sentinel, RediSearch, RedisJSON, and all Redis features.

Details

Jedis is the official Redis client library for Java developed and maintained by Redis Labs. It provides simple and intuitive APIs while accessing all Redis features. It covers enterprise-level features including efficient connection management with JedisPool, distributed processing with Redis Cluster, high availability with Redis Sentinel, pipelining and transactions, Pub/Sub messaging, and Lua scripting support. The JedisPooled class simplifies the traditional try-with-resources pattern, enabling more concise Redis operations. It also supports Redis modules like RediSearch, RedisJSON, and RedisTimeSeries for advanced search, JSON operations, and time-series data processing. With easy integration through Maven and Gradle, comprehensive documentation, and active community support, it is widely adopted as the standard Redis client in the Java ecosystem.

Pros and Cons

Pros

  • Official Support: Official development and maintenance by Redis Labs
  • Rich Features: Complete support for all Redis features and modules (RediSearch, RedisJSON, etc.)
  • High-Performance Connection Pooling: Efficient resource management with JedisPool
  • Concise API: Intuitive and user-friendly Java API design
  • Cluster Support: Automatic discovery and failover for Redis Cluster
  • Enterprise Ready: Complete support for Sentinel, TLS, and authentication
  • Active Community: Rich documentation and sample code

Cons

  • Synchronous Focused: Limited support for asynchronous processing
  • Connection Management Complexity: Need to optimize pool size and timeout settings
  • Java Ecosystem Limited: Cannot be used outside Java/JVM languages
  • Dependencies: Requires dependency libraries like Commons Pool and Apache HTTP Client
  • Error Handling: Need to implement retry logic for connection errors

Official Links

Code Examples

Basic Setup and Maven Dependency

<!-- pom.xml -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>5.1.0</version>
</dependency>

Simple Operations with JedisPooled

import redis.clients.jedis.JedisPooled;

public class RedisExample {
    public static void main(String[] args) {
        // Connection with JedisPooled (recommended method)
        JedisPooled jedis = new JedisPooled("localhost", 6379);
        
        // Basic operations
        jedis.set("key", "value");
        String value = jedis.get("key");
        System.out.println(value); // "value"
        
        // Set key with expiration
        jedis.setex("tempkey", 60, "temporary value"); // Expires in 60 seconds
        
        // List operations
        jedis.lpush("mylist", "element1", "element2", "element3");
        List<String> list = jedis.lrange("mylist", 0, -1);
        System.out.println(list);
        
        // Set operations
        jedis.sadd("myset", "member1", "member2", "member3");
        Set<String> members = jedis.smembers("myset");
        System.out.println(members);
    }
}

Connection Management with JedisPool

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Jedis;

public class JedisPoolExample {
    private static JedisPool pool;
    
    static {
        // Pool configuration
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(20); // Maximum connections
        poolConfig.setMaxIdle(10);  // Maximum idle connections
        poolConfig.setMinIdle(2);   // Minimum idle connections
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        
        // Pool initialization
        pool = new JedisPool(poolConfig, "localhost", 6379, 2000, "password");
    }
    
    public void performOperations() {
        // Safe connection management with try-with-resources
        try (Jedis jedis = pool.getResource()) {
            jedis.set("pooled-key", "pooled-value");
            String value = jedis.get("pooled-key");
            System.out.println("Retrieved: " + value);
            
            // Complex operations
            jedis.hset("user:1", "name", "John Doe");
            jedis.hset("user:1", "email", "[email protected]");
            jedis.hset("user:1", "age", "30");
            
            Map<String, String> user = jedis.hgetall("user:1");
            System.out.println("User data: " + user);
        }
    }
    
    public static void close() {
        if (pool != null) {
            pool.close();
        }
    }
}

Redis Cluster Operations

import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.HostAndPort;

import java.util.HashSet;
import java.util.Set;

public class ClusterExample {
    public static void main(String[] args) {
        // Cluster nodes configuration
        Set<HostAndPort> jedisClusterNodes = new HashSet<>();
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7380));
        jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7381));
        
        // Cluster connection
        JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes);
        
        // Data operations in cluster
        jedisCluster.set("cluster-key", "cluster-value");
        String value = jedisCluster.get("cluster-key");
        System.out.println("Cluster value: " + value);
        
        // Place multiple keys in the same hash slot
        jedisCluster.set("{user:1000}:profile", "user profile data");
        jedisCluster.set("{user:1000}:preferences", "user preferences");
        
        // Performance counters
        jedisCluster.incr("page_views");
        Long views = jedisCluster.get("page_views");
        System.out.println("Page views: " + views);
        
        jedisCluster.close();
    }
}

Pipelining and Transactions

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.Response;

public class AdvancedOperations {
    public void demonstratePipelining() {
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            // Execute multiple commands in batch with pipelining
            Pipeline pipeline = jedis.pipelined();
            
            Response<String> set1 = pipeline.set("pipe1", "value1");
            Response<String> set2 = pipeline.set("pipe2", "value2");
            Response<Long> incr = pipeline.incr("counter");
            Response<List<String>> lrange = pipeline.lrange("mylist", 0, -1);
            
            // Execute batch
            pipeline.sync();
            
            // Get results
            System.out.println("Set result: " + set1.get());
            System.out.println("Counter value: " + incr.get());
            System.out.println("List contents: " + lrange.get());
        }
    }
    
    public void demonstrateTransaction() {
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            // Transaction with optimistic locking
            String watchKey = "balance:1000";
            
            jedis.watch(watchKey);
            String balance = jedis.get(watchKey);
            int currentBalance = Integer.parseInt(balance != null ? balance : "0");
            
            if (currentBalance >= 100) {
                Transaction tx = jedis.multi();
                tx.decrBy(watchKey, 100);
                tx.incrBy("balance:2000", 100);
                
                List<Object> results = tx.exec();
                if (results == null) {
                    System.out.println("Transaction failed due to concurrent modification");
                } else {
                    System.out.println("Transaction successful: " + results);
                }
            } else {
                jedis.unwatch();
                System.out.println("Insufficient balance");
            }
        }
    }
}

Pub/Sub Messaging

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class PubSubExample {
    
    // Custom message listener
    static class MessageListener extends JedisPubSub {
        @Override
        public void onMessage(String channel, String message) {
            System.out.println("Received message: " + message + " from channel: " + channel);
        }
        
        @Override
        public void onSubscribe(String channel, int subscribedChannels) {
            System.out.println("Subscribed to channel: " + channel);
        }
        
        @Override
        public void onUnsubscribe(String channel, int subscribedChannels) {
            System.out.println("Unsubscribed from channel: " + channel);
        }
        
        @Override
        public void onPMessage(String pattern, String channel, String message) {
            System.out.println("Pattern message: " + message + " from " + channel + " matching " + pattern);
        }
    }
    
    public static void main(String[] args) {
        // Publisher
        Thread publisherThread = new Thread(() -> {
            try (Jedis jedis = new Jedis("localhost", 6379)) {
                for (int i = 0; i < 10; i++) {
                    jedis.publish("news", "Breaking news #" + i);
                    jedis.publish("weather", "Weather update #" + i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        // Subscriber
        Thread subscriberThread = new Thread(() -> {
            try (Jedis jedis = new Jedis("localhost", 6379)) {
                MessageListener listener = new MessageListener();
                jedis.subscribe(listener, "news", "weather");
            }
        });
        
        subscriberThread.start();
        publisherThread.start();
        
        try {
            publisherThread.join();
            subscriberThread.interrupt();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

Using RediSearch and RedisJSON

import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.search.*;
import redis.clients.jedis.json.Path;
import com.google.gson.Gson;

public class ModulesExample {
    
    static class Product {
        public String name;
        public String category;
        public double price;
        public String description;
        
        public Product(String name, String category, double price, String description) {
            this.name = name;
            this.category = category;
            this.price = price;
            this.description = description;
        }
    }
    
    public static void main(String[] args) {
        JedisPooled jedis = new JedisPooled("localhost", 6379);
        Gson gson = new Gson();
        
        // RedisJSON operations
        Product product = new Product("Laptop", "Electronics", 999.99, "High-performance laptop");
        jedis.jsonSet("product:1", gson.toJson(product));
        
        String productJson = jedis.jsonGet("product:1");
        System.out.println("Stored product: " + productJson);
        
        // RediSearch index creation
        Schema schema = new Schema()
                .addTextField("name", 5.0)
                .addTextField("description", 1.0)
                .addTagField("category")
                .addNumericField("price");
                
        IndexDefinition def = new IndexDefinition()
                .setPrefixes(new String[]{"product:"});
                
        try {
            jedis.ftCreate("product-index", IndexOptions.defaultOptions().setDefinition(def), schema);
        } catch (Exception e) {
            // Index already exists
            System.out.println("Index already exists");
        }
        
        // Execute search
        Query query = new Query("laptop")
                .addFilter(new Query.NumericFilter("price", 500, 1500))
                .limit(0, 10);
                
        SearchResult result = jedis.ftSearch("product-index", query);
        System.out.println("Search results: " + result.getDocuments());
        
        jedis.close();
    }
}