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

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

相关推荐
hui函数2 小时前
Flask电影投票系统全解析
后端·python·flask
haogexiaole3 小时前
Redis优缺点
数据库·redis·缓存
在未来等你3 小时前
Redis面试精讲 Day 27:Redis 7.0/8.0新特性深度解析
数据库·redis·缓存·面试
小厂永远得不到的男人4 小时前
基于 Spring Validation 实现全局参数校验异常处理
java·后端·架构
川石课堂软件测试5 小时前
技术干货|使用Prometheus+Grafana监控Tomcat实例详解
redis·功能测试·单元测试·tomcat·测试用例·grafana·prometheus
毅航8 小时前
从原理到实践,讲透 MyBatis 内部池化思想的核心逻辑
后端·面试·mybatis
两张不够花8 小时前
Shell脚本源码安装Redis、MySQL、Mongodb、PostgreSQL(无报错版)
linux·数据库·redis·mysql·mongodb·postgresql·云计算
展信佳_daydayup8 小时前
02 基础篇-OpenHarmony 的编译工具
后端·面试·编译器
Always_Passion8 小时前
二、开发一个简单的MCP Server
后端
用户721522078778 小时前
基于LD_PRELOAD的命令行参数安全混淆技术
后端