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部署,需要注意总线端口的映射

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

相关推荐
这里有鱼汤12 分钟前
分享一个实用的主力抄底的“三合一指标”:主力吸货 + 风险 + 趋势
后端
IT_陈寒1 小时前
React性能优化:这5个Hook技巧让我的组件渲染效率提升50%(附代码对比)
前端·人工智能·后端
Captaincc1 小时前
9 月 20 日,TRAE Meetup@Guangzhou 相聚羊城
人工智能·后端
Brookty1 小时前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
风象南1 小时前
SpringBoot Jar包冲突在线检测
后端
程序员爱钓鱼1 小时前
Go语言实战案例 — 项目实战篇:任务待办清单 Web 应用
后端·google·go
波波烤鸭1 小时前
Redis 高可用实战源码解析(Sentinel + Cluster 整合应用)
数据库·redis·sentinel
Cyan_RA93 小时前
SpringMVC @RequestMapping的使用演示和细节 详解
java·开发语言·后端·spring·mvc·ssm·springmvc
MarkHard1239 小时前
如何利用redis使用一个滑动窗口限流
数据库·redis·缓存