客户端在哨兵failover后仍连旧主,根本原因是未及时更新拓扑且未重建连接池;需订阅__sentinel__:hello、主动拉取权威地址、原子切换新连接池,并加超时兜底与错误重连机制。哨兵 failover 后客户端还在连旧主节点?根本原因是客户端没及时收到拓扑变更通知,或者收到了但没触发连接池重建。Redis 哨兵本身不主动推送完整拓扑,只通过 PUBLISH 在 sentinel:hello 频道广播简短消息,内容只有发送者 IP:port 和当前已知的主节点名------不含新主地址、从节点列表、甚至不带版本号或序列号,无法判断是否为最新状态。常见错误现象:NoReplicationTargetError、ConnectionRefusedError、写请求发到已降级为从节点的老主上并报 READONLY 错误。必须自己订阅 sentinel:hello 频道,并解析每条消息中的 master-name 和 ip:port 字段不能只靠一次解析就更新;需维护本地缓存的「主节点地址」和「最后收到该 master-name 消息的时间戳」,避免被延迟到达的旧消息覆盖收到消息后,要立刻调用 SENTINEL get-master-addr-by-name <master-name> 主动拉取当前权威地址,而不是直接信消息里的 ip:port(它可能是另一个哨兵的地址)连接池没重建,光刷新地址也没用很多客户端库(比如 Jedis、Lettuce 默认配置、redis-py 的 ConnectionPool)在初始化后,即使你手动改了 host/port,底层 TCP 连接、路由缓存、甚至 pipeline 状态都不会自动失效。它们不是"动态 DNS 式"刷新,而是"静态快照式"持有。使用场景:高可用服务上线初期压测时一切正常,但真实 failover 发生后,部分实例持续失败 10--60 秒,日志里反复出现对旧地址的重试。不要在运行中 patch connection_pool.connection_kwargs ------ 这不会影响已建立的连接,也不会触发新连接使用新参数正确做法是:拿到新主地址后,创建全新 ConnectionPool 实例,并让上层业务代码(如 DAO 层)原子切换引用;旧 pool 调用 close() 或交由 GC 清理Lettuce 用户注意:RedisClient.setUri() 不会刷新现有连接,必须重建 StatefulRedisConnection;推荐用 RedisClient.connect(new RedisURI())订阅监听卡住或漏消息?检查 pub/sub 生命周期PUB/SUB 连接天生脆弱:TCP 断开无心跳保活、重连后不自动恢复订阅、断线期间消息全丢。很多实现把监听逻辑塞进一个长期运行的线程,却没处理网络抖动或哨兵重启导致的连接中断。 MacsMind 电商AI超级智能客服
相关推荐
m0_676544385 小时前
MySQL如何配置不同级别的事务锁_调整innodb_locks_unsafe_for_binlogdFObBIMmai5 小时前
mysql索引区分度不足如何解决_mysql多列索引组合优化神明9315 小时前
SQL处理JOIN查询中数据倾斜的问题_散列连接键或增加缓存m0_591364735 小时前
c++ 实时傅里叶变换stft c++如何进行音频的频谱分析2401_832365525 小时前
MySQL无法修改数据表结构_检查磁盘空间与元数据锁l1t5 小时前
类似 X-13ARIMA-SEATS 功能的 JDemetra+ 安装和使用小熊Coding5 小时前
懂车帝汽车销售数据可视化分析系统X56616 小时前
c++ aot编程 c++如何使用oneapi进行跨平台并行编程2501_901006476 小时前
如何按优先级控制 Flex 容器中子元素的截断顺序