DEBUG.WIKI
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
雨云;给项目一台云服务器
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →

ioredis Sentinel 重连反复选旧节点,健康地址被跳过

ioredis6.0.0在预ready断开和角色不符时有不同的Sentinel游标路径。核对实际发现顺序与拓扑,不能只靠增加重试或关闭角色校验。

ioredis 已配置多个 Sentinel,切换后却反复连接同一个旧地址;其他 Sentinel 能返回健康主节点,客户端仍迟迟无法 ready。这时除了网络、认证与主服务名,还要检查客户端实际按什么顺序询问 Sentinel。

正式 ioredis 6.0.0 的 SentinelConnector 有两条需要分开的游标路径:开启 failoverDetector 后,连接尚未 ready 就关闭,下一轮可能再次从同一个 Sentinel 开始;关闭检测器时,节点角色不符的处理又可能跳过紧随其后的 Sentinel。增加重试次数不一定能让被跳过的端点获得机会。

TCP 已连接,不等于 Redis 已就绪

第一种情况中,Sentinel A 返回的节点能够建立 TCP,但在 INFO 就绪检查阶段断开;B 返回的是健康节点。启用 failoverDetector 时,检测器在 socket connect 上初始化,调整共享 Sentinel 迭代器的位置。节点还没 ready,后续失败重试便可能重新选择 A。

第二种情况不依赖开启检测器。A、B、C、D 四个已知 Sentinel 中,A 和 C 的视图过期,返回的节点实际已是副本;B 和 D 返回正确主节点。角色检查连续推进迭代器再重置,可能形成 A、C、A、C 的顺序,而不是逐个询问。

已知列表还可能因为 updateSentinels 增加。不能只数最初配置的两个地址,就断言运行中没有这种组合。另一方面,仅看到连接失败,也不能直接证明撞上了这里的游标问题。

先留下发现顺序,再决定临时恢复方式

在受控日志中记录每次询问的 Sentinel 地址、返回的数据节点、角色检查结果,以及连接是否到达 ready。认证信息和完整业务命令不要写入日志。用同一主服务名分别核对 Sentinel 视图,并在权限允许时确认返回节点的实际角色。

仅第一种预 ready 断开条件,且应用确实显式开启了 failoverDetector 时,可以在隔离验证后评估暂时关闭该可选检测器。它会改变切换通知行为,不是无代价修复,也解决不了第二种角色不匹配时的跳过路径。

已确认某些 Sentinel 的视图过期,应由负责高可用拓扑的人处理其状态与连接问题。确需临时调整客户端列表时,保留原配置、可靠冗余与可达性检查,并安排恢复;不能为了绕过顺序而永久只留一个地址,也不能把数据节点 IP 冒充 Sentinel 地址。

实际目标是主节点时,仍保留角色校验。不要通过改成 slave、关闭 ready 检查或允许副本写入,让错误节点获得接收业务写请求的机会。若已经出现 READONLY,可先按实际写入端点的角色检查确认应用连到了哪里。

重连策略不能代替请求完成边界

retryStrategy 管理数据连接重试,sentinelRetryStrategy 管理发现 Sentinel 失败后的重试;二者不是同一个计数器。为交互式请求保留现有截止时间和可观测失败,不靠无限排队掩盖长时间无法 ready。后台消费者的等待要求可能不同,应独立配置。

截至 2026 年 10 月 25 日,正式 6.0.0 仍保留上述共享迭代器与角色检查实现。选择后续版本时,要核对实际包中的修正,再覆盖预 ready 断开、角色不符、最后一个 Sentinel 失败以及 ready 后断线,不能仅凭“可以连上一次”验收。

连接恢复也不表示先前请求一定没有执行。对计数、入队或状态修改,仍以业务幂等身份核对结果,不因重连失败立即重放整批命令。