redis-cli -c 连接后set/get频繁超时是因客户端无重试机制,遇moved/ask重定向即中断;真实原因多为集群拓扑变更或网络抖动,需结合cluster nodes、scaninterval调优及client-output-buffer-limit配置综合排查。

redis-cli -c 连接后执行 SET/GET 时频繁超时
这不是 Redis 服务挂了,而是客户端在集群拓扑变更或网络抖动时无法快速重选节点。默认 redis-cli -c 不带重试逻辑,一次失败就报错,比如:MOVED 12345 192.168.1.101:7002 或 ASK 12345 192.168.1.102:7003 后直接中断。真实环境里,网络延迟突增到 200ms+、丢包率 5% 就足以触发这类现象。
实操建议:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 用
redis-cli -c -h 127.0.0.1 -p 7001连上任意节点,手动发SET和GET,观察是否稳定返回;若失败,立刻执行cluster nodes看当前拓扑是否已更新 - 不要依赖单次命令结果,改用循环脚本持续探测:
for i in {1..100}; do redis-cli -c -h 127.0.0.1 -p 7001 SET testkey$i $i 2>/dev/null && echo "$i ok" || echo "$i fail"; sleep 0.1; done - 重点看失败是否集中在某几个 slot —— 若是,说明对应主节点所在机器正经历网络隔离,而非全局抖动
用 tc 模拟延迟和丢包后 client-output-buffer-limit 触发连接断开
当网络延迟升高、从节点同步变慢,主节点的 client-output-buffer 可能堆积,超出 client-output-buffer-limit 配置就会强制断开复制连接,导致从节点降级为 fail 状态。这不是配置写错了,而是该参数默认值(如 slave 256mb 64mb 60)在高延迟下不够宽松。
实操建议:
- 在主节点配置中显式调大缓冲区:把
client-output-buffer-limit slave 512mb 128mb 120加入redis.conf,再redis-cli config rewrite生效 - 用
tc施加可控干扰前,先在主节点运行redis-cli info replication | grep output,记录初始output_buffer_length值作为基线 - 模拟后若看到
master_link_status:down,说明缓冲区溢出已发生,此时需结合cluster-node-timeout(建议设为 ≥120000)延长故障判定窗口
iptables DROP 后出现 “CLUSTERDOWN Hash slot not served” 错误
这是典型的脑裂(split-brain)场景:网络分区导致部分节点认为其他节点 fail,但又没完成足够多数派投票,集群拒绝服务写请求。错误信息 CLUSTERDOWN Hash slot not served 表明至少一个槽位没有健康主节点提供服务,不是客户端连不上,而是集群主动拒绝路由。
实操建议:
- 分区前用
redis-cli cluster info | grep cluster_state确认状态是ok;分区后立即查cluster nodes,观察是否出现大量fail标记且角色混乱(如原主节点显示myself,master,fail) - 避免在测试中用
debug segfault模拟宕机——它不触发网络分区,只会走标准故障转移流程,掩盖真实脑裂风险 - 恢复网络后,
cluster nodes中仍标fail的节点不会自动复活,必须人工执行cluster forget <node-id></node-id>+cluster meet重建握手,这点常被忽略
Redisson 客户端在分区恢复后仍向旧主节点发请求
Redisson 默认开启 checkSlotsCoverage=true,启动时校验所有 16384 个槽是否被覆盖,但运行中若未及时刷新拓扑,它会继续往已失效的主节点地址发命令,抛出 RedisConnectionException。这不是重连失败,而是缓存了过期的 slots 映射。
实操建议:
- 把
scanInterval从默认 1000ms 改为 200ms(单位毫秒),加快拓扑感知速度:Config config = new Config();config.useClusterServers().setScanInterval(200);
- 禁用
checkSlotsCoverage仅适用于开发验证,生产必须保留;真正要解决的是pingConnectionInterval—— 设为 3000ms 可让连接层更快发现 TCP 断连 - 遇到
MOVED重定向时,Redisson 内部会更新本地 slots 缓存,但前提是没开启sslEnable且没配错password;密码错误会导致重定向失败并静默 fallback 到旧节点
cluster nodes 输出里哪怕只有一个节点标 fail,只要它负责的槽没被其他节点接管,整个集群就处于半不可用状态——这种“局部不可用”比全集群宕机更难定位。










