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:
- 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.
- 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部署,需要注意总线端口的映射
如果文章对你有帮助,点赞+收藏~~