必须在所有集群节点统一配置tcp-keepalive,因redis集群通信为多跳链路,任一跳(如客户端→入口节点或节点间)未启用保活,中间设备(防火墙/nat/云lb)均可能静默断连,导致“假死”;服务端配置保障节点间及bus连接,客户端sdk需单独配keepalive保障首跳,二者缺一不可。

必须在所有集群节点(master 和 replica)上统一配置 tcp-keepalive,否则链路中任一节点未启用,整条路径仍可能被中间设备静默断开。
为什么单配客户端或服务端都不够
Redis 集群通信是多跳的:客户端 → 入口节点 → 重定向 → 目标节点。任意一跳空闲超时,都可能被防火墙、NAT 网关、云负载均衡器等中间设备切断连接,但双方 TCP 状态仍显示 ESTABLISHED(即“假死”)。服务端 tcp-keepalive 只管节点间通信;客户端(如 Lettuce、redis-py)需单独开启自己的 TCP keepalive,否则客户端→入口节点这第一跳就不可靠。
- 服务端配置影响的是
redis-cli cluster nodes返回的节点之间、以及节点与 bus 端口之间的长连接存活 - 客户端 SDK 的 keepalive(如 Lettuce 的
ClientResources配置)控制的是应用进程到 Redis 入口节点的连接保活 - 两者缺一不可,且超时参数建议错开:服务端设为 300s,客户端设为 240s,避免探测包同时发出造成抖动
如何正确设置 redis.conf 中的 tcp-keepalive
在每个集群节点的 redis.conf 中添加或修改这一行:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
tcp-keepalive 300
注意三个关键点:
- 值不能小于 30:部分公有云(如阿里云 SLB、AWS NLB)会对间隔
- 不能依赖系统内核参数(如
net.ipv4.tcp_keepalive_time):Redis 自己调用setsockopt(SO_KEEPALIVE)并控制探测逻辑,优先级更高 - 改完必须执行
redis-cli CONFIG REWRITE或重启节点;仅CONFIG SET不会持久化,且部分旧版本不支持运行时修改该参数
验证配置是否真正生效
别只看配置文件写了没,要确认运行时已加载:
- 连任一节点执行:
redis-cli CONFIG GET tcp-keepalive,返回值应为["tcp-keepalive","300"] - 检查实际 socket 状态(Linux):
ss -tno | grep :6379,观察某连接的timer字段是否显示keepalive及剩余秒数 - 若用
redis-cli -c模拟客户端行为后仍频繁报Connection reset by peer或卡在MOVED重定向,大概率是某节点漏配或客户端没开 keepalive
最容易被忽略的是:cluster bus(节点间广播通道)也走 TCP,且默认复用 tcp-keepalive 设置——但如果你手动改了 cluster-announce-bus-port 却忘了同步调整防火墙策略,keepalive 包会被拦截,导致集群状态同步延迟甚至分裂。这个细节,连很多运维手册都没提。










