Redis集群断网后不会自动剔除故障节点,需满足cluster-node-timeout超时且多数主节点共识才标记fail并触发故障转移。

Redis集群断网后会不会自动剔除故障节点
不会自动剔除,至少不会立刻剔除。Redis Cluster 的故障检测依赖 cluster-node-timeout 配置(默认 15000ms),且需多数主节点达成共识才能将某节点标记为 fail。若只断一个从节点,集群通常无感知;但若断的是主节点,且超时后多数主节点确认其失联,才会触发故障转移——前提是它有合格的从节点(满足 cluster-require-full-coverage no 且从节点未掉线、复制偏移足够新)。
常见误判点:CLUSTER NODES 输出中看到某个节点状态是 fail?(带问号),只是“疑似失败”,不是最终状态;真正变成 fail 才会启动从节点提升流程。预演时务必用 redis-cli --cluster check 或轮询 CLUSTER INFO 观察 cluster_state 和 cluster_slots_assigned 是否稳定。
用 chaos-mesh 模拟 Redis 节点网络隔离的最小可行配置
Chaos Mesh 是目前对 Kubernetes 中 Redis Cluster 故障注入最可控的工具。关键不是“能不能断网”,而是“断得够不够准”:必须精确到 Pod 级别 + 端口级(只封 6379 和 16379),否则控制总线(16379)被断会导致误判扩散。
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: redis-node-netcut
spec:
action: partition
mode: one
selector:
pods:
- namespace: redis-cluster
labels:
app.kubernetes.io/component: redis-node
statefulset.kubernetes.io/pod-name: redis-node-2
direction: both
target:
selector:
pods:
- namespace: redis-cluster
labels:
app.kubernetes.io/component: redis-node
mode: all
network-delay:
latency: "0ms"
duration: "60s"
- 务必设
action: partition(单向隔离),而非loss(丢包)——后者会让心跳包偶尔穿透,干扰故障判定逻辑 -
direction: both表示进出都断,避免出现“能收不能发”的半通状态,这种状态最容易卡在fail?阶段不推进 - 测试完立刻删掉 Chaos 对象,否则下次预演可能叠加影响;用
kubectl delete networkchaos redis-node-netcut
断网后如何验证客户端是否真的发生了连接重试和拓扑刷新
光看 Redis Cluster 自身状态不够,客户端才是最终承压方。Jedis、Lettuce、redis-py 等主流客户端行为差异很大:Jedis 默认不自动刷新槽映射,Lettuce 默认开启 adaptiveRefreshTriggersInterval,redis-py 则依赖 redis.cluster.RedisCluster 初始化时的 reinitialize_steps。
实操建议:
- 在客户端代码里打开日志:Lettuce 加
-Dio.lettuce.core.tracing=debug,redis-py 设logging.getLogger("redis.cluster").setLevel(logging.DEBUG) - 主动触发一次跨槽命令,比如
SET key:12345 value(哈希槽 12345),观察日志里是否出现Trying to retrieve cluster topology或Redirecting to - 不要依赖
PING命令判断连通性——它可能走本地连接池缓存,实际发出去的是旧拓扑下的目标地址;改用CLUSTER SLOTS,这个命令强制走当前已知的任意节点并要求返回最新分片信息
为什么在测试环境做断网预演,仍可能漏掉生产问题
测试环境的拓扑密度、连接复用率、客户端版本、代理层(如 Twemproxy、Redis Exporter)都和生产不同。最常被忽略的两点:
- 生产环境往往启用了
tcp_keepalive(Linux 内核参数net.ipv4.tcp_keepalive_time),而测试环境 Docker/K8s 默认关闭,导致断网后连接长时间滞留“ESTABLISHED”状态,客户端无法及时感知断连 - 集群规模差异:3 主 3 从的测试集群,
cluster-node-timeout过期后只需 2 个主节点同意即可标记fail;但生产 9 主 9 从,需要 5 票,网络抖动更容易造成短暂fail?波动,进而引发不必要的主从切换
真正有效的预演,不是“断一次看它活没活着”,而是连续三次在不同节点上执行 30 秒断网,中间间隔 2 分钟,并监控 cluster_stats_messages_sent_fail 和客户端 ConnectionRefused 异常率曲线——这两处毛刺,才是上线前必须压平的信号。


















