5

I was trying to connect to JedisCluster (ElastiCache Redis) from java. But I was getting JedisConnectionException with No reachable node in the cluster.

Here was my code to connect to JedisCluster

public static void main(String[] args) throws IOException{
        final GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxWaitMillis(2000);
        poolConfig.setMaxTotal(300);
        Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
        jedisClusterNode.add(new HostAndPort("mycachecluster.eaogs8.0001.usw2.cache.amazonaws.com",6379));
        jedisClusterNode.add(new HostAndPort("mycachecluster.eaogs8.0002.usw2.cache.amazonaws.com",6379));
        JedisCluster jedisCluster = new JedisCluster(jedisClusterNode,poolConfig);
        System.out.println("Cluster Size...." + jedisCluster.getClusterNodes().size());
        try{
            jedisCluster.set("foo", "bar");
            jedisCluster.get("foo");
        }
        catch(Exception e){
            e.printStackTrace();
        }
        finally{
            jedisCluster.close();
        }
    }

The exception I got after running this

redis.clients.jedis.exceptions.JedisNoReachableClusterNodeException: No reachable node in cluster
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnection(JedisSlotBasedConnectionHandler.java:57)
    at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:74)
    at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:116)
    at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:31)
    at redis.clients.jedis.JedisCluster.set(JedisCluster.java:103)

I have checked

telnet mycachecluster.eaogs8.0001.usw2.cache.amazonaws.com 6379

as mentioned in AWS Doc I got the reply as Connected.

What is the issue here and why I am not able to connect to the JedisCluster using java?

Note :

I am using jedis version 2.9.0

Update:

In AWS Encryption in-transit and Encryption at-rest are activated

So

Jedis jedis = null;
        try{
            jedis = new Jedis(URI.create("rediss://mycachecluster.eaogs8.0001.usw2.cache.amazonaws.com:6379"));
            System.out.println(jedis.ping());
            System.out.println("XXXXX: "+jedis.get("c"));
        }
        catch(Exception exception){
            exception.printStackTrace();
        }
        finally{
            jedis.close();
        }

works fine. But not the jedis cluster.

Unknown
  • 2,037
  • 3
  • 30
  • 47
  • 1
    You might want to try out Redisson or Lettuce clients that have Redis Cluster with SSL support. – mp911de Jan 28 '18 at 18:37
  • I am facing the same problem. I am using AWS Elasticache (cluster mode enabled) with no encryption in transit. In Jedis, I initialize only one HostPort i.e. the AWS Elasticache Redis configuration endpoint. How did you solve this issue ? – Sourajit Basak Aug 04 '21 at 13:11

2 Answers2

4

From URI.create("rediss://..."), it's evident that you are using Redis SSL Scheme to create a successful connection by Jedis. But JedisCluster doesn't have SSL support yet.

There is a pending feature request regarding this.

sazzad
  • 5,740
  • 6
  • 25
  • 42
1

The JedisCluster had some problems while connecting the redis cluster server with SSL enabled. Even with the latest revision(as of July 2020) we were getting the exception JedisNoReachableClusterNodeException. There are very less articles on the configurations required for various server requirements.

We needed the library in 2 languages, one in Java and the other in Python. For python I used the python redis-py-cluster. While for Java initially we tried with Jedis and then Jedis Cluster but both were not helpful. So another library I found is

Lettuce

For a redis cluster server with SSL support the configuration is pretty straight forward and supports a builder pattern to construct the connection object with optional parameters. Here is the sample to create and connect to redis-cluster server

RedisURI redisURI = RedisURI.Builder.redis("<<Redis Server primary endpoint>>", 6379).withSsl(true).withVerifyPeer(false).build();
RedisClusterClient redisClient  = RedisClusterClient.create(redisURI);
StatefulRedisClusterConnection<String, String> conn = redisClient.connect();
List<KeyValue<String, String>> res_1=  conn.sync().mget(keys...)_
conn.close();

But note that if the redis server is a single node instance then even Jedis library is also good to use.

Mithun Theertha
  • 131
  • 2
  • 6