ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Redis集群主从切换后,我的客户端为什么还在往旧主写?

Redis集群主从切换后,我的客户端为什么还在往旧主写? 一场凌晨的故障从告警到冷汗凌晨3点我正盯着手机上的告警「Redis集群主节点故障触发自动切换」。这本该是个好消息——Sentinel正常工作了但接下来的监控曲线却让我冷汗直冒客户端QPS断崖式下跌部分请求超时而旧主节点的写入流量居然还在持续我们用的是Java生态客户端是JedisRedis版本5.0。集群规模不大6节点单主双从但承载了核心业务的缓存和分布式锁。问题来了为什么主从切换后有些客户端像“瞎了”一样依然固执地向已经降级的旧主写入数据根因客户端“固执”的背后1. Jedis的拓扑缓存陷阱Jedis默认会缓存集群拓扑信息包括节点角色。当Sentinel完成主从切换后Jedis不会立即感知到拓扑变化除非显式调用JedisCluster#clusterSlots或JedisCluster#refreshCluster当前连接触发了MOVED或ASK重定向错误关键机制Jedis的拓扑刷新是惰性 的。如果你没有配置定时刷新或触发重定向客户端可能直到连接超时才会发现主节点变化。2. 连接池的“雪上加霜”更糟糕的是连接池中的长连接会复用旧主节点的TCP连接。即使Sentinel广播了新主节点信息这些“僵尸连接”依然会继续向旧主写入——直到旧主彻底拒绝连接或超时。// 错误写法没有处理拓扑刷新的JedisCluster初始化 JedisCluster jedis new JedisCluster(nodes, timeout, poolConfig); // 请求仍然可能被路由到旧主 jedis.set(key, value); // 正确写法配置自动刷新需Jedis 3.7 ClusterClientOptions options ClusterClientOptions.builder() .autoReconnect(true) .pingBeforeActivateConnection(true) .topologyRefreshOptions( TopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() // 自适应触发刷新 .refreshTriggersReconnectAttempts(3) .build() ).build(); JedisCluster jedis new JedisCluster(nodes, timeout, timeout, 5, password, poolConfig);数据对比刷新策略的影响我们在测试环境模拟主从切换对比不同配置下的恢复时间配置方案平均感知延迟数据丢失风险默认无刷新5-30秒高定时刷新30秒5秒中自适应刷新重试1秒低结论仅靠定时刷新不够——网络分区或Sentinel延迟可能导致刷新失效自适应刷新基于错误触发更可靠。避坑清单你必须知道的4个细节别依赖“默认配置”Jedis的默认拓扑刷新策略极其保守生产环境必须显式配置。版本陷阱Jedis 3.x以下版本对动态拓扑的支持极差建议至少升级到3.7。双重验证即使配置了自动刷新也要在客户端埋点监控主节点变化日志。连接池清理主从切换后强制清空连接池调用JedisCluster#close并重建实例是最彻底的方式。终极解法从客户端到架构的防御最终我们的解决方案是分层防御客户端层启用自适应刷新 定期心跳PING检测连接健康度代理层对读写请求强制走代理如Twemproxy但引入额外延迟监控层通过Redis的INFO replication实时比对客户端与服务端的主节点视图// 监控示例定期检查主节点一致性 public void checkMasterConsistency(JedisCluster jedis) { String currentMaster jedis.clusterNodes().split(\n) .stream().filter(line - line.contains(myself,master)) .findFirst() .orElseThrow(); if (!currentMaster.equals(lastKnownMaster)) { logger.warn(Master changed from {} to {}, lastKnownMaster, currentMaster); jedis.close(); // 强制重建连接 } }写在最后Redis的主从切换不是“银弹”客户端的拓扑感知比你想象的更脆弱。真正的稳定性来自于“不信任任何自动故障转移”的防御式编程。你在项目中是怎么处理这类问题的欢迎评论区聊聊你的“血泪史”。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进