#Error while connecting to Redis cluster created using TestContainer module using JedisCluster client

4 messages · Page 1 of 1 (latest)

graceful nebula
#

Code snippet for starting container:

Network network = Network.newNetwork();
RedisContainer redisContainer = new RedisContainer(DockerImageName.parse("redis:7.0.5"))
                    .withExposedPorts(port)
                    .withCommand("redis-server --port " + port +
                            " --requirepass " + redisPassword +  // Password for clients
                            " --masterauth " + redisPassword +  // Password for inter-node communication
                            " --cluster-enabled yes" +
                            " --cluster-config-file nodes.conf"+
                            " --cluster-node-timeout 5000"+
                            " --appendonly yes" +
                            " --bind 0.0.0.0" )
                    .withNetwork(network)
                    .withNetworkMode("bridge")
                    .withNetworkAliases("redis-" + i)
                    .waitingFor(Wait.forListeningPort());
#
  1. Single-Node Cluster

I attempted to create a single-node cluster with cluster-enabled set to yes and replica set to 0. I tried connecting to it using JedisCluster.

Issues and Fixes:

Initially, I got the error: Cluster slots not allocated. I resolved this by running the CLUSTER ADDSLOTS command to allocate the slot range. After this, I ran the CLUSTER NODES command and got the following output:

1f2673c5fdb45ca16d564658ff88f815db5cbf01 172.29.0.2:6379@16379 myself,master - 0 0 1 connected 0-16383
However, when I tried connecting to the cluster using JedisCluster, connection got established, I was able to get nodes list with ip and port using jedisCluster.getClusterNodes() api. When I tried writing some key value pair got below error after few seconds.

redis.clients.jedis.exceptions.JedisClusterOperationException: Cluster retry deadline exceeded.

Oddly enough, running commands via redis-cli worked perfectly for both writing and reading data. Cluster Info Output:

cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:1
cluster_size:1
cluster_current_epoch:1
cluster_my_epoch:1
cluster_stats_messages_pong_sent:1
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:2
cluster_stats_messages_pong_received:1
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:2
total_cluster_links_buffer_limit_exceeded:0
Cluster Slots Output:

1) 1) (integer) 0
   2) (integer) 16383
   3) 1) "172.29.0.2"
      2) (integer) 6379
      3) "b47f7da9be31ce953d4b4fbf9e3a737d1c9b7a58"
      4) (empty array)
#
  1. Multi-Node Cluster

I also tried setting up a 6-node cluster (3 masters and 3 slaves).

Observations:

JedisCluster.getClusterNodes() returned the correct node information for all 3 master nodes (IP and port). However, when I tried writing data to the cluster using JedisCluster, I got the following error:

redis.clients.jedis.exceptions.JedisClusterOperationException: Cluster retry deadline exceeded.
When I used redis-cli -c to write data, it got stuck at the Redirecting to slot [<some slot>] located at <ip> node message.

Possible Issue I'm trying to bring up redis in a container using TestContainer module. I suspect the nodes in the cluster are unable to communicate with each other properly. In the case of the single-node cluster, some configuration might still be missing. Some

Any help in resolving this issue would be greatly appreciated. Thanks!

#

JedisCluster Config code:

// Using redisContainer in above code snippet start the container and run  <redis-cli --no-auth-warning -h localhost -p 6379 -a password cluster addslotsrange 0 16383> to add slots and continue with below code

        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(Runtime.getRuntime().availableProcessors()); 
        poolConfig.setMaxIdle(Runtime.getRuntime().availableProcessors());
        poolConfig.setMinIdle(Runtime.getRuntime().availableProcessors());
        poolConfig.setMaxWaitMillis(2000);

//        Connect to the cluster using Jedis with a password
        DefaultJedisClientConfig.Builder jedisClientConfig = DefaultJedisClientConfig.builder()
                .password(redisPassword)
                .ssl(false)
                .connectionTimeoutMillis(10000)
                .socketTimeoutMillis(4000);

        final Set<HostAndPort> hosts = new HashSet<>(redisContainers.size());
        int i = 0;
        for(RedisContainer redisContainer : redisContainers){
            String redisHost = "127.0.0.1";
            int redisPort = redisContainer.getMappedPort(basePort+i);
            hosts.add(new HostAndPort(redisHost, redisPort));
            i += 1;
        }

        System.out.println("Hosts " + hosts);

        try (JedisCluster jedis = new JedisCluster(hosts, jedisClientConfig.build(), 3, poolConfig)) {
            Map<String, redis.clients.jedis.ConnectionPool> nodes = jedis.getClusterNodes();
            System.out.println("Connected cluster nodes: " + nodes);
            nodes.forEach((key, value) -> System.out.println(key));
            jedis.set("key", "value"); // This is where the error is seen
            System.out.println("Key set in Redis Cluster: " + jedis.get("key"));
        }