Docker部署Redis Cluster时 Waiting for the cluster to join太长时间

Docker部署Redis Cluster时 Waiting for the cluster to join太长时间,问题排查、解决

编写docker-compose.yaml文件去部署Redis集群,文件如下

yaml 复制代码
networks:
  redis-net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.30.1.0/24

services:
  redis-0:
    image: redis:latest
    container_name: redis-0
    networks:
      redis-net:
        ipv4_address: 172.30.1.2
    ports:
      - "7000:6379"
    volumes:
      - ./7000/data:/data
      - ./7000/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-1:
    image: redis:latest
    container_name: redis-1
    networks:
      redis-net:
        ipv4_address: 172.30.1.3
    ports:
      - "7001:6379"
    volumes:
      - ./7001/data:/data
      - ./7001/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-2:
    image: redis:latest
    container_name: redis-2
    networks:
      redis-net:
        ipv4_address: 172.30.1.4
    ports:
      - "7002:6379"
    volumes:
      - ./7002/data:/data
      - ./7002/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-3:
    image: redis:latest
    container_name: redis-3
    networks:
      redis-net:
        ipv4_address: 172.30.1.5
    ports:
      - "7003:6379"
    volumes:
      - ./7003/data:/data
      - ./7003/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-4:
    image: redis:latest
    container_name: redis-4
    networks:
      redis-net:
        ipv4_address: 172.30.1.6
    ports:
      - "7004:6379"
    volumes:
      - ./7004/data:/data
      - ./7004/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-5:
    image: redis:latest
    container_name: redis-5
    networks:
      redis-net:
        ipv4_address: 172.30.1.7
    ports:
      - "7005:6379"
    volumes:
      - ./7005/data:/data
      - ./7005/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf

执行启动,没有任何问题,建立每一个主节点都有一个从节点的集群,命令如下

shell 复制代码
redis-cli --cluster create 192.168.3.222:7000 192.168.3.222:7001 \
192.168.3.222:7002 192.168.3.222:7003 192.168.3.222:7004 192.168.3.222:7005 \
--cluster-replicas 1

在这个时候发现不对劲,Waiting for the cluster to join的时间太长,等了5分钟

sql 复制代码
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
........................................................................................................................................................................................^C

感觉不符合常理,然后查阅官方文档,部分原文如下

Redis Cluster TCP ports

Every Redis Cluster node requires two open TCP connections: a Redis TCP port used to serve clients, e.g., 6379, and second port known as the cluster bus port . By default, the cluster bus port is set by adding 10000 to the data port (e.g., 16379); however, you can override this in the **cluster-port** configuration.

Cluster bus is a node-to-node communication channel that uses a binary protocol, which is more suited to exchanging information between nodes due to little bandwidth and processing time. Nodes use the cluster bus for failure detection, configuration updates, failover authorization, and so forth. Clients should never try to communicate with the cluster bus port, but rather use the Redis command port. However, make sure you open both ports in your firewall, otherwise Redis cluster nodes won't be able to communicate.

For a Redis Cluster to work properly you need, for each node:

  1. The client communication port (usually 6379) used to communicate with clients and be open to all the clients that need to reach the cluster, plus all the other cluster nodes that use the client port for key migrations.
  2. The cluster bus port must be reachable from all the other cluster nodes.

If you don't open both TCP ports, your cluster will not work as expected.

大致意思是说,集群的每一个节点需要打开两个端口,一个用于为客户端提供服务的端口(port),另一个为集群的总线端口(cluster-bus-port),为节点与节点之间通信使用,默认情况下,集群总线端口(cluster-bus-port)是10000+(port)。

如果没有打开这两个 TCP 端口,集群将无法按预期工作。

到这里就知道原因了,首先服务器的防火墙需要开放对应的端口,其次容易被忽略的地方是,使用docker部署时,应该需要把总线端口(cluster-bus-port)也映射出来。

防火墙开放端口,如下

shell 复制代码
# 防火墙开放8080端口
firewall-cmd --zone=public --add-port=7000-7004/tcp --permanent
firewall-cmd --zone=public --remove-port=17000-17004/tcp --permanent
## 重载配置
sudo firewall-cmd --reload
## 查看所有开启的端口
firewall-cmd --zone=public --list-ports
# 重启
systemctl restart firewalld
# 停止
systemctl stop firewalld

修改后的docker-compose.yaml文件

yaml 复制代码
networks:
  redis-net:      # 定义一个网络名称
    driver: bridge  # 指定了网络的驱动类型,容器连接到 bridge 网络时,它们通过一个私有的虚拟桥接网络来通信,通常用于同一主机上的容器之间的通信
    ipam:   # 控制网络的 IP 地址分配
      driver: default   # 使用了 default 驱动,这意味着 Docker 将使用默认的 IPAM 配置方式来管理 IP 地址
      config:
        - subnet: 172.30.1.0/24 # 定义了一个子网(subnet)

services:
  redis-0:
    image: redis:latest
    container_name: redis-0
    networks:
      redis-net:
        ipv4_address: 172.30.1.2
    ports:
      - "7000:7000"
      - "17000:17000"
    volumes:
      - ./7000/data:/data
      - ./7000/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-1:
    image: redis:latest
    container_name: redis-1
    networks:
      redis-net:
        ipv4_address: 172.30.1.3
    ports:
      - "7001:7001"
      - "17001:17001"
    volumes:
      - ./7001/data:/data
      - ./7001/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-2:
    image: redis:latest
    container_name: redis-2
    networks:
      redis-net:
        ipv4_address: 172.30.1.4
    ports:
      - "7002:7002"
      - "17002:17002"
    volumes:
      - ./7002/data:/data
      - ./7002/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-3:
    image: redis:latest
    container_name: redis-3
    networks:
      redis-net:
        ipv4_address: 172.30.1.5
    ports:
      - "7003:7003"
      - "17003:17003"
    volumes:
      - ./7003/data:/data
      - ./7003/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-4:
    image: redis:latest
    container_name: redis-4
    networks:
      redis-net:
        ipv4_address: 172.30.1.6
    ports:
      - "7004:7004"
      - "17004:17004"
    volumes:
      - ./7004/data:/data
      - ./7004/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf
  redis-5:
    image: redis:latest
    container_name: redis-5
    networks:
      redis-net:
        ipv4_address: 172.30.1.7
    ports:
      - "7005:7005"
      - "17005:17005"
    volumes:
      - ./7005/data:/data
      - ./7005/conf:/usr/local/etc/redis/
    environment:
      TZ: Asia/Shanghai
    command: redis-server /usr/local/etc/redis/redis.conf

出现Waiting for the cluster to join的时间太长这个,就是节点之间通信的端口没有被映射,如果使用docker部署,需要注意总线端口的映射

如果文章对你有帮助,点赞+收藏~~

相关推荐
AI人H哥会Java28 分钟前
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
java·开发语言·spring boot·后端·架构
计算机学长felix32 分钟前
基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·后端
sin220132 分钟前
springboot数据校验报错
spring boot·后端·python
loop lee1 小时前
Redis - Token & JWT 概念解析及双token实现分布式session存储实战
java·redis
程序员大阳1 小时前
闲谭Scala(1)--简介
开发语言·后端·scala·特点·简介
直裾1 小时前
scala图书借阅系统完整代码
开发语言·后端·scala
大大怪将军~~~~2 小时前
SpringBoot 入门
java·spring boot·后端
凡人的AI工具箱2 小时前
每天40分玩转Django:Django缓存
数据库·人工智能·后端·python·缓存·django