Search code examples
spring-bootdockerdocker-composeredislettuce

lettuce can't connect to docker redis


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


Solution

  • 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();