ChthollyHub
  • Hub
  • Chtholly
  • Search
  • Write
  • Login

Chtholly Hub

|

Rekyrice
@Rekyrice

动漫 · 追番 · 随笔

7文章50标签1活跃
珂朵莉 - default
Observation

珂朵莉观察

今天仓库里还算安静。没有关系,安静的时候也适合读一点东西。

社区入口

写点什么把今天的故事放进仓库搜索仓库找文章、番剧和灵感珂朵莉房间看看她最近在想什么

热门标签

动画电影Agent制作考察Java动画演出动画评论性能排查牛尾宪辅独立游戏生活随笔1000xRESIST3DCGasyncioCITY THE ANIMATIONCosplay

活跃用户

Rekyrice7 篇最近文章

最新文章

  • 即使无法生活,也可以停留——《末日后酒店》与那些比世界活得更久的东西
  • 裕太终于把那句话说完了——《古立特宇宙》
  • 欢迎来到 Chtholly Hub
  • 2026 冬季追番清单
  • 为什么叫 Chtholly

© 2026 Rekyrice · Chtholly Hub

Powered by Next.js & Spring Boot

公安备案图标桂公网安备45020502000330号·桂ICP备2026017801号-1

HubChthollySearchWrite
Redis 明明还活着,为什么请求还是一批批超时

Redis 明明还活着,为什么请求还是一批批超时

2026年04月27日磁盘又满了
约 8 分钟磁盘又满了
RedissonRedis ClusterMOVED故障复盘

这篇是对 redisson/redisson #5972 公开排障记录的复盘,不是作者亲历,也没有在本地搭一套三主三从集群复现。记录里的环境是 Redis 6.0.11、Redisson 3.30.0。集群频繁发生主备切换,服务随后一批批超时,重启又能暂时恢复。像极了磁盘又满了:现象熟,第一反应也熟,顺手一修往往修偏。

一条很会带路的报错

公开日志最扎眼的是这几行:

RedisTimeoutException: Unable to acquire connection!
Increase connection pool size.
NodeSource [slot=7685, addr=redis://10.xxx.xxx.213:6379,
redirect=MOVED] ... after 3 retry attempts

看到 Unable to acquire connection,再接一句 Increase connection pool size,连接池几乎会立刻成为嫌疑人。池太小、并发太高、借连接等太久,都是常见路径。先调大,再观察。操作很顺。

问题也在这里。错误文本提供的是通用处置提示,不能自动替整段上下文下结论。若连接池只是容量不足,日志里那个 redirect=MOVED 很难解释。它不是背景噪声。它说明这次执行已经碰到 Redis Cluster 的重定向语义。

日志中同一时刻有两个工作线程报出近似异常,slot 都是 7685,地址一致,重试三次后失败。这里没有足够证据计算池利用率,也没有监控曲线能证明连接数耗尽。直接改池大小,只是在有力提示和关键线索之间选了更顺眼的那个。

当场排查时,可以把“池不够”和“路由没收敛”拆成两张证据表。连接池这边看等待、占用、创建失败和配置是否触顶;集群路由这边看报错 slot 当时归谁、客户端认为归谁、MOVED 指向谁。前一张表没有数据,就别把提示语当结案;后一张表若出现同一 slot 持续指向旧节点,方向已经很具体。

还要对齐时间。主备切换发生在什么时候,第一条 MOVED 在什么时候,成批超时从什么时候开始,重启又在什么时候完成。四个时间点能把“切换之后”从一句印象变成可检查的顺序。#5972 没提供完整时间线,所以这篇只保留公开日志里的报错时刻,不补造切换耗时。

根据公开 Issue 日志排版的超时片段

公开日志按原顺序节选排版,地址已一致脱敏;画面不是本地终端执行结果。

MOVED 藏在 NodeSource 里

NodeSource 给了三个有用字段:slot=7685、一个具体节点地址、redirect=MOVED。这里最容易读错的是地址。按 Redisson 3.30.0 的 RedisExecutor,客户端先按 slot 映射选择目标;收到 RedisMovedException 后,再解析异常里的目标 URL,构造 new NodeSource(ex.getSlot(), ip, Redirect.MOVED) 并重新执行。因此这条异常中的 addr 是 MOVED 指向的重定向目标,也是后续尝试连接的目标,不是最初接到请求的旧节点。

单看一条 MOVED 并不稀奇。集群切换或槽位归属变化时,客户端收到重定向,再继续请求,本来可以是一段短暂过程。#5972 首帖报告者判断 Redisson 保存的拓扑有概率没有刷新,请求因此发往不再承担该槽位的节点。这个判断描述了故障路径,却没有在首帖异常里留下初始节点;要确认第一跳去了哪里,仍需 DEBUG 请求日志,或切换前后的拓扑快照。

后续社区记录补上了这类证据。在 Redis 7.0.14、Redisson 3.32.0 的小环境里,贡献者用 failover 后再 failback 的步骤复现;DEBUG 日志显示请求先按旧映射落到已变成副本的目标,收到 MOVED 后才以带地址的 NodeSource 连接当前主节点。首帖报告者还观察到 Redisson 内部有四个 master,而实际集群只有三个。它们是后续参与者的复现与观察,不等于这篇文章自行复现。

切换后,请求仍沿着旧地图走

把路径压缩一下:客户端手里的 topology 仍把 slot 指向旧映射目标;failback 后这个目标已经是副本,请求照着旧地图发过去;该节点返回 MOVED,给出当前主节点地址;Redisson 再用该地址构造当前 NodeSource 并尝试重定向连接。若拓扑没有收敛,后续请求仍会反复走第一段旧路线,外部看到的就是 Redis 进程还活着,业务却持续超时。

主从切换后的旧拓扑请求路径示意

根据公开 Issue 后续 DEBUG 现象绘制,只表达旧映射目标(当前副本)、MOVED 与当前主节点的关系,不是实测拓扑。

图里没有三主三从的全部节点,也没有网络延迟、连接池数量或切换耗时。它只区分两阶段:旧映射决定第一跳,MOVED 的目标地址决定重定向尝试。首帖异常只呈现第二阶段的 NodeSource,不能拿其中的 addr 反推第一跳。

服务侧健康检查若只问端口能否连接,也会给出过于乐观的答案。节点能接受连接,不代表客户端对每个 slot 的映射都正确。更贴近业务的检查应发出与线上路径相同的读写请求,并把响应节点、slot 和重定向一起记下。这里不预设阈值,只要求观察对象能覆盖故障路径。

三主三从也不能简化成“还有五台机器,所以可用”。副本数量描述的是部署结构,请求是否成功还经过客户端路由、连接获取、重定向和重试。任一环节停在旧状态,存活节点数量就无法直接换算成业务成功率。

重启为什么能救一阵

Issue 描述称服务需要重启才能解决。重启会重新建立客户端、连接和集群视图,所以旧的内存状态被清掉后,客户端有机会从当前集群重新拿到拓扑。请求随即恢复,并不等于连接池调整生效,也不等于集群从此稳定。

“有机会”三个字要留着。公开 Issue 没给出重启前后的拓扑快照,也没给重启后持续稳定的时间。这里只能把暂时恢复理解为与客户端状态重建相容,不能把它写成已经证明的内部根因。若下一次主备切换又留下旧视图,同一条路仍可能回来。

值班时可以把重启当止血动作,但要同时留证。至少记录切换时间、客户端当前节点表、slot 对应关系、MOVED 的目标地址和恢复时间。否则每次只剩一句“重启好了”,故障复盘会再次退回连接池猜谜。

关闭状态不是本地验收

GitHub timeline 显示维护者引用了 commit a4bdaa5,随后回复 Fixed. 并关闭 Issue;commit 标题是 Fixed - re-added master node isn't updated in Cluster topology. #5972。Issue 同时被归入 3.33.0 milestone。这些是上游的修复记录,不能扩大成 3.33.0 解决了所有拓扑问题。本文没有自行复现,也没有验证 3.33.0 在原三主三从环境的效果。

工程动作可以更具体。升级前在预发准备可重复的主备切换场景,给业务请求施加稳定负载;同时观察客户端拓扑刷新、slot 路由、MOVED 数量、连接获取失败和恢复耗时。若旧版本能稳定触发现象,再对候选版本跑同一套步骤,结果才可比较。连接池指标也要看,但别只看连接池。

压测记录要能回答一次切换里发生了什么:哪些 slot 改变归属,客户端何时看到新主节点,期间有多少请求收到 MOVED,超时是否在停止切换后自行消退。若只能给出平均延迟,短时间成批失败很容易被稀释。保留逐阶段的错误分布,才能判断恢复来自版本行为,还是来自重启或集群恰好稳定下来。

验收条件应写成可检查的句子:切换后拓扑在预期窗口内更新,请求不持续落到旧节点,MOVED 不形成成批超时,客户端无需重启即可收敛。没有这些证据,Issue 的 Closed 和 milestone 只能说明上游项目如何归档,不能替代自己的发布判断。

RedissonRedis ClusterMOVED故障复盘
阅读轨迹
约 8 分钟2,265 字2026年04月27日
阅读进度0%
本文目录
  1. 一条很会带路的报错
  2. MOVED 藏在 NodeSource 里
  3. 切换后,请求仍沿着旧地图走
  4. 重启为什么能救一阵
  5. 关闭状态不是本地验收
文章线索
磁盘又满了
RedissonRedis ClusterMOVED故障复盘
珂朵莉陪读
珂朵莉 - serious

看起来很认真呢……我会安静地在旁边陪着。

解释这篇文章
磁盘又满了

作者

磁盘又满了

主要写 Java 和 Python 的排错记录,偶尔也记一点跑模型时踩过的坑。

查看作者所有文章
珂朵莉 - curious

文章问答

问珂朵莉关于这篇文章

她会先读这篇文章,再安静地回答你的问题。可以继续追问。

评论

加载中…

登录后参与讨论