javarediscluster-computingpooljedis

Jedis TLS connection to Redis Cluster


We are using Redis enterprise edition 5 shards: host:6379 - 6383 endpoint: redis-endpoint.example.com 6378 Using Jedis 4.3.x, it works ok when I use JedisPooled

GenericObjectPoolConfig<Connection> genericPoolConfig = new GenericObjectPoolConfig<>();
genericPoolConfig.setMaxIdle(4);
genericPoolConfig.setMaxTotal(5);
genericPoolConfig.setMinIdle(2);

JedisClientConfig clientConfig = DefaultJedisClientConfig.builder()
      .sslSocketFactory(sslContext.getSocketFactory()) // key/trust stores here
      .ssl(true)
      .user("user_here")
      .password(redisPassword)
      .hostnameVerifier(hostnameVerifier)
      .build();
JedisPooled jedis = new JedisPooled(genericPoolConfig, new HostAndPort("redis-endpoint.example.com", 6378), clientConfig);
jedis.set("key_1", "value_1"); // this cmd works

But when I try to use JedisCluster, it throws Exception

Set<HostAndPort> jedisClusterNodes = new HashSet<>();
jedisClusterNodes.add(new HostAndPort("redis-endpoint.example.com", 6378));
JedisCluster cluster = new JedisCluster(jedisClusterNodes, clientConfig, 3, genericPoolConfig); // <== ERROR here
cluster.set("key_2", "value_2"); 

I got errors:

Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException: ERR command is not allowed
    at redis.clients.jedis.Protocol.processError(Protocol.java:96)
    at redis.clients.jedis.Protocol.process(Protocol.java:137)
    at redis.clients.jedis.Protocol.read(Protocol.java:192)
    at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:316)
    at redis.clients.jedis.Connection.getUnflushedObjectMultiBulkReply(Connection.java:282)
    at redis.clients.jedis.Connection.getObjectMultiBulkReply(Connection.java:287)
    at redis.clients.jedis.JedisClusterInfoCache.executeClusterSlots(JedisClusterInfoCache.java:320)
    at redis.clients.jedis.JedisClusterInfoCache.discoverClusterNodesAndSlots(JedisClusterInfoCache.java:60)
    at redis.clients.jedis.providers.ClusterConnectionProvider.initializeSlotsCache(ClusterConnectionProvider.java:42)
    at redis.clients.jedis.providers.ClusterConnectionProvider.<init>(ClusterConnectionProvider.java:33)
    at redis.clients.jedis.UnifiedJedis.<init>(UnifiedJedis.java:122)
    at redis.clients.jedis.JedisCluster.<init>(JedisCluster.java:173)
    at redis.clients.jedis.JedisCluster.<init>(JedisCluster.java:167)

Questions:

  1. Should I put all 5 shards in Set jedisClusterNodes or just need to put cluster endpoint.
  2. Any things I did incorrectly when using new JedisCluster(jedisClusterNodes, clientConfig, 3, genericPoolConfig);?
  3. will JedisPooled work well for cluster mode?

Solution

  • BY DEFAULT, you should be considering the Redis Enterprise (RE) as a single node from client side. So you can use JedisPooled to communicate with RE.

    Note 1: Cluster specific commands are actually disabled in default mode. That's what you can see in error message ERR command is not allowed.

    Note 2: Redis Enterprise has a OSS Cluster mode where cluster specific commands are allowed. Only in this RE mode you should be using JedisCluster to communicate instead of JedisPooled.