I create a redis cluster with docker-compose and when I try to connect the cluster from my local machine with a java app, which also docker is located in, but lettuce gets timeout while jedis connects to cluster. Lettuce connects to main servers which are 7001 7002 7003 and after that it discover other nodes and again try to connect them and gets time out. Here is my code.
Docker-compose.yml
version: '3.8'
networks:
redis-net:
name: redis-net
driver: bridge
ipam:
driver: default
config:
- subnet: 10.0.0.0/16
services:
redis-cluster:
image: redis:latest
container_name: redis-cluster
command: redis-cli --cluster create 10.0.0.11:6379 10.0.0.12:6379 ... --cluster-replicas 1 --cluster-yes
depends_on:
- redis-1
- redis-2
...
networks:
redis-net:
ipv4_address: 10.0.0.2
redis-1:
build: ./redis
container_name: redis-1
image: redis-cluster-node
networks:
redis-net:
ipv4_address: 10.0.0.11
ports:
- 7001:6379
redis-2:
image: redis-cluster-node
container_name: redis-2
networks:
redis-net:
ipv4_address: 10.0.0.12
ports:
- 7002:6379
...
redis_commander:
image: rediscommander/redis-commander:latest
container_name: redis_web
environment:
REDIS_HOSTS: "local:redis-1:6379,local:redis-2:6379,..."
ports:
- "5000:8081"
depends_on:
- redis-1
- redis-2
...
networks:
redis-net:
ipv4_address: 10.0.0.3
Dockerfile
FROM redis:latest
COPY redis.conf /etc/redis/redis.conf
ENTRYPOINT ["redis-server","/etc/redis/redis.conf"]
redis.conf
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
appendonly yes
maxmemory-policy volatile-lru
maxmemory 3gb
bind 0.0.0.0
Test class
public static void lettuce() {
RedisURI node1 = RedisURI.Builder.redis("localhost",7001).build();
RedisURI node2 = RedisURI.Builder.redis("localhost",7002).build();
RedisURI node3 = RedisURI.Builder.redis("localhost",7003).build();
RedisClusterClient redisClient = RedisClusterClient.create(Arrays.asList(node1, node2, node3));
ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder().dynamicRefreshSources(false).build();
redisClient.setOptions(ClusterClientOptions.builder()
.topologyRefreshOptions(topologyRefreshOptions)
.build());
StatefulRedisClusterConnection<String, String> connection = redisClient.connect();
RedisAdvancedClusterCommands<String, String> syncCommands = connection.sync();
syncCommands.set("test key", "test value");
}
Error
2022-02-12 11:06:11.494 WARN 21392 --- [ioEventLoop-6-4] i.l.core.cluster.RedisClusterClient : connection timed out: /10.0.0.12:6379
2022-02-12 11:06:21.530 WARN 21392 --- [ioEventLoop-6-5] i.l.core.cluster.RedisClusterClient : connection timed out: /10.0.0.11:6379
2022-02-12 11:06:31.564 WARN 21392 --- [ioEventLoop-6-6] i.l.core.cluster.RedisClusterClient : connection timed out: /10.0.0.13:6379
2022-02-12 11:06:41.586 WARN 21392 --- [ioEventLoop-6-7] i.l.core.cluster.RedisClusterClient : connection timed out: /10.0.0.14:6379
2022-02-12 11:06:51.625 WARN 21392 --- [ioEventLoop-6-8] i.l.core.cluster.RedisClusterClient : connection timed out: /10.0.0.16:6379
2022-02-12 11:07:01.635 WARN 21392 --- [ioEventLoop-6-1] i.l.core.cluster.RedisClusterClient : connection timed out: /10.0.0.15:6379
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:94)
at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:352)
at io.lettuce.core.cluster.RedisClusterClient.connect(RedisClusterClient.java:400)
at io.lettuce.core.cluster.RedisClusterClient.connect(RedisClusterClient.java:375)
at com.exercise.redis.utils.RedisShardedPoolUtils.lettuce(RedisShardedPoolUtils.java:47)
at com.exercise.redis.RedisExerciseApplication.main(RedisExerciseApplication.java:12)
... 5 more
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /10.0.0.15:6379
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:261)
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:170)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:503)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Thanks
I found the solution with bitnami-redis here is my docker-compose.yml
services:
redis-0:
image: bitnami/redis-cluster
container_name: redis-0
restart: always
networks:
redis-net:
ipv4_address: 172.22.0.100
environment:
- 'REDIS_PORT_NUMBER=7000'
- 'ALLOW_EMPTY_PASSWORD=yes'
- 'REDIS_NODES=redis-0 redis-1 redis-2 redis-3 redis-4 redis-5'
- 'REDIS_CLUSTER_ANNOUNCE_PORT=7000'
- 'REDIS_CLUSTER_ANNOUNCE_IP=192.168.0.13' --local ip--
- 'REDIS_CLUSTER_BUS_ANNOUNCE_PORT=17000'
- 'REDIS_CLUSTER_DYNAMIC_IPS=no'
ports:
- "7000:7000"
- "17000:17000"
redis-1:
image: bitnami/redis-cluster
container_name: redis-1
restart: always
networks:
redis-net:
ipv4_address: 172.22.0.101
environment:
- 'REDIS_PORT_NUMBER=7001'
- 'ALLOW_EMPTY_PASSWORD=yes'
- 'REDIS_NODES=redis-0 redis-1 redis-2 redis-3 redis-4 redis-5'
- 'REDIS_CLUSTER_ANNOUNCE_PORT=7001'
- 'REDIS_CLUSTER_ANNOUNCE_IP=192.168.0.13' --local ip--
- 'REDIS_CLUSTER_BUS_ANNOUNCE_PORT=17001'
- 'REDIS_CLUSTER_DYNAMIC_IPS=no'
ports:
- "7001:7001"
- "17001:17001"
redis-2:
image: bitnami/redis-cluster
container_name: redis-2
restart: always
networks:
redis-net:
ipv4_address: 172.22.0.102
environment:
- 'REDIS_PORT_NUMBER=7002'
- 'ALLOW_EMPTY_PASSWORD=yes'
- 'REDIS_NODES=redis-0 redis-1 redis-2 redis-3 redis-4 redis-5'
- 'REDIS_CLUSTER_ANNOUNCE_PORT=7002'
- 'REDIS_CLUSTER_ANNOUNCE_IP=192.168.0.13' --local ip--
- 'REDIS_CLUSTER_BUS_ANNOUNCE_PORT=17002'
- 'REDIS_CLUSTER_DYNAMIC_IPS=no'
ports:
- "7002:7002"
- "17002:17002"
--- other nodes
redis-cluster-init:
image: redis:6.2
container_name: redis-cluster-init
restart: 'no'
networks:
redis-net:
ipv4_address: 172.22.0.106
depends_on:
- redis-0
- redis-1
- redis-2
- redis-3
- redis-4
- redis-5
entrypoint: []
command:
- /bin/bash
- -c
- redis-cli --cluster create 172.22.0.100:7000 172.22.0.101:7001 172.22.0.102:7002 172.22.0.103:7003 172.22.0.104:7004 172.22.0.105:7005 --cluster-replicas 1 --cluster-yes
redis_commander:
image: rediscommander/redis-commander:latest
container_name: redis_web
environment:
REDIS_HOSTS: "local:redis-0:7000,local:redis-1:7001,local:redis-2:7002,local:redis-3:7003,local:redis-4:7004,local:redis-5:7005"
ports:
- "5000:8081"
depends_on:
- redis-1
- redis-2
- redis-3
- redis-4
- redis-5
- redis-0
- redis-cluster-init
networks:
redis-net:
ipv4_address: 172.22.0.107
networks:
redis-net:
name: redis-net
driver: bridge
ipam:
config:
- subnet: 172.22.0.0/16
Here is my lettuce code
RedisURI redis0 = RedisURI.create("127.0.0.1",7000);
RedisURI redis1 = RedisURI.create("127.0.0.1",7001);
RedisURI redis2 = RedisURI.create("127.0.0.1",7002);
RedisClusterClient clusterClient = RedisClusterClient.create(Arrays.asList(redis1,redis2,redis0));
StatefulRedisClusterConnection<String, String> connection = clusterClient.connect();
RedisAdvancedClusterCommands<String, String> syncCommands = connection.sync();