用 iptables 模拟 Redis 哨兵网络分区需双向封禁节点间通信(INPUT+OUTPUT),匹配 6379/26379 端口,确保 Quorum 计算失效;恢复时须精准删除规则而非清空链,避免锁死服务器。

怎样用 iptables 模拟 Redis 哨兵集群的网络分区
直接断网最可靠,但生产环境不能动物理链路;iptables 是唯一能精准控制节点间连通性的方案。关键不是“封端口”,而是按 IP 对封双向通信,否则哨兵会因单向延迟误判。
- 必须同时 DROP
INPUT和OUTPUT链的流量,只封 INPUT 会导致本机仍能发心跳但收不到响应,行为不等于真实分区 - 目标规则要匹配
redis-server和redis-sentinel共用的端口(默认6379和26379),否则哨兵进程自己还能连通,Quorum 计算失效 - 先用
iptables -L -n -v确认规则生效,再用telnet <ip> 26379</ip>从其他节点验证是否真断开
为什么哨兵没触发故障转移?检查 Quorum 是否被满足
哨兵不切换,大概率是 quorum 参数没凑够——它指“多少个哨兵达成一致”,不是“存活哨兵数”,也不是“总哨兵数”。分区后,各子集群各自计票,但只有 ≥ quorum 的子集群才能发起 failover。
-
quorum值必须 ≤ 实际部署的哨兵总数,且建议设为 ⌊N/2⌋+1(如 3 个哨兵设2,5 个设3),否则分区后永远无法达标 - 检查每个哨兵的
sentinel known-sentinel输出,确认它看到的其他哨兵列表是否和你预期的分区一致;如果某个哨兵还“以为”其他节点在线,说明iptables规则漏了或没刷新连接缓存 - 注意:哨兵默认每 10 秒发一次 ping,但主观下线(
sdown)判定需连续失败 30 秒(down-after-milliseconds 30000),别刚封就去查日志
Redis 主从切换后客户端连不上?重点看 sentinel get-master-addr-by-name 返回值
客户端靠哨兵查新主地址,不是靠自己重连旧 IP。如果返回空或旧地址,说明哨兵集群本身没同步成功,或者客户端没轮询所有哨兵。
- 手动在每个哨兵上执行
sentinel get-master-addr-by-name mymaster,对比输出是否一致;不一致说明 Quorum 未达成,或哨兵间配置的sentinel monitor名称不统一 - 客户端初始化时必须提供全部哨兵地址(不止一个),否则可能连到尚未完成状态同步的哨兵,拿到过期信息
- 某些 SDK(如 Jedis)默认只连第一个哨兵,需显式启用
setSentinels并传入完整列表
测试完怎么安全恢复?别直接 iptables -F
iptables -F 会清掉所有规则,包括你可能依赖的防火墙策略(比如 SSH 白名单)。分区测试后,必须只删自己加的规则,否则可能锁死服务器。
- 加规则时用
-I INPUT 1插入最前,并记下行号;恢复时用iptables -D INPUT精准删除 - 更稳妥的做法:把测试规则加到自定义链(如
SENTINEL_TEST),测试完iptables -X SENTINEL_TEST即可 - 恢复后立刻检查
redis-cli -p 26379 info sentinel | grep leader,确认所有哨兵重新选出同一 leader,而不是分裂成多个“主”
真实网络分区比 iptables 复杂得多——丢包、高延迟、DNS 解析失败都可能干扰哨兵判断。iptables 只能验证 Quorum 逻辑是否跑通,不能替代线上多轮压测。










