redis集群需每个节点独立配置cluster-enabled yes,且必须正确设置bind、protected-mode、集群总线端口(服务端口+10000)、cluster-announce-ip等,否则节点无法发现或握手失败。

cluster-enabled yes 必须在每个节点独立配置
集群模式不是主从或哨兵那种“中心化启用”,而是每个 Redis 实例必须自己声明“我要当集群节点”。只在一个节点设 cluster-enabled yes,其他节点还是单机模式,它们根本不会识别彼此的集群握手请求。
常见错误现象:CLUSTER NODES 返回空,或者只有本机 ID;redis-cli --cluster check 报错 No such node 或连接被拒绝;节点间 MEET 失败,日志里反复出现 Unable to connect to node。
- 每台机器上的
redis.conf都要加这一行:cluster-enabled yes - 配套必须设
cluster-config-file nodes-6379.conf(文件名可变,但不能多个实例共用同一文件) -
cluster-node-timeout 5000建议显式设置,避免默认 15 秒在内网也显得太长 - 如果用 systemd 管理,确认
ExecStart没有通过--port覆盖配置文件里的port,否则集群通信端口会错乱
bind 和 protected-mode 导致集群握手失败
Redis 集群节点靠 TCP 互相发现、交换心跳、重定向请求,一旦网络层不通,整个集群就卡死。最常踩的坑是:本地测试时 bind 127.0.0.1 或 protected-mode yes 拦住了跨机器连接。
使用场景:三台服务器部署 3 主 3 从,但 redis-cli --cluster create 卡在 “Waiting for the cluster to join…”。
-
bind不能只写127.0.0.1,得加上实际对外通信的 IP,比如bind 127.0.0.1 192.168.1.10 -
protected-mode yes时,只要bind不包含127.0.0.1,且没配requirepass,就会直接拒绝所有外部连接 —— 集群节点全被拦在外面 - 生产环境建议关掉
protected-mode,改用防火墙控制端口访问,而不是靠 Redis 自身开关
集群端口 = 服务端口 + 10000,且必须放行
Redis 集群节点除监听客户端端口(如 6379),还会自动监听一个集群总线端口(如 16379)。这个端口走的是二进制协议,用于故障检测、配置更新、failover 协调。它不走 Redis 协议,普通 telnet 或 curl 测不通,但防火墙必须开。
错误现象:cluster nodes 显示部分节点状态为 fail? 或 noaddr;日志里持续刷 Marking node XXX as failing;即使网络 ping 得通,集群仍无法稳定。
- 若服务端口是
6379,集群总线端口固定是16379;8000 → 18000,以此类推 - Linux 上检查:
ss -tlnp | grep :16379,确认进程在监听,且没被 SELinux 或 firewalld 拦截 - Docker 场景下,
-p 6379:6379 -p 16379:16379必须显式映射,仅映射 6379 是不够的
cluster-announce-ip 容易被忽略,尤其在 Docker/NAT 环境
节点启动后,会把自己的 IP 和端口写进 nodes-xxx.conf 并广播给其他节点。如果它填的是容器内网 IP(如 172.18.0.3)或 NAT 后的私有地址,其他节点连不上,集群就分裂。
典型场景:Docker Compose 启动 6 个 redis 容器,redis-cli --cluster create 成功,但一重启容器,集群立刻不可用。
- 强制指定对外可达 IP:
cluster-announce-ip 192.168.1.10(填宿主机真实 IP 或负载均衡 VIP) - 同时补上端口:
cluster-announce-port 6379和cluster-announce-bus-port 16379,避免自动推导出错 - 该配置项 5.0.1+ 才支持,旧版本只能靠 host 网络模式或复杂 iptables 规则绕过
集群不是配置完就能跑稳的系统,节点间网络可见性、IP 声明准确性、端口开放完整性,三者缺一不可。少设一个 cluster-announce-ip,可能等你上线一周后才在扩容时暴露问题。










