确认 client-output-buffer-limit 导致全量复制断连,需在主节点执行 CLIENT LIST 过滤 flags=S,重点检查 omem > 67108864 且持续增长、oll ≠ 0、age 大但 idle 小,并 grep 日志中 "Client closed connection due to output buffer limit"。

怎么确认是 client-output-buffer-limit 导致的全量复制断连
主从全量复制期间反复断开,先别改配置,直接查证据。关键不是看 INFO replication 里状态变来变去,而是盯住主节点上那个从库连接的真实内存占用——omem 字段。
执行 CLIENT LIST,过滤出 flags=S 的行,重点看三列:
-
omem持续 > 67108864(64MB)且还在涨:基本坐实是缓冲区打满被主节点主动踢了 -
oll(output list length)不为 0:说明有命令在输出队列里卡着没发完 -
age很大但idle很小:从节点收得勤,但处理/写入慢,缓冲区清不掉
再补一手验证:查主节点日志,grep "output buffer" /var/log/redis/redis-server.log,如果看到 Client closed connection due to output buffer limit,就不用再猜了。
client-output-buffer-limit 的三个参数到底怎么影响全量同步
默认值 client-output-buffer-limit slave 256mb 64mb 60 在全量同步时非常危险,不是因为数值小,而是它定义了三种断连触发条件:
- 硬限制(256mb):缓冲区占用一旦超这个数,立刻断连,不讲情面
- 软限制(64mb):缓冲区连续 60 秒内 ≥ 64mb,也会断连——而全量同步期间 RDB 正在发送,这个条件极易满足
- time(60):软限制的持续时间窗口,60 秒对几百 MB 的 RDB 来说太短
注意:repl-backlog-size 对全量同步完全无效,它只管增量命令。全量同步走的是另一套缓冲通道,只受 client-output-buffer-limit slave 约束。
调参前必须做的三件事,否则改了也白改
光跑 CONFIG SET client-output-buffer-limit "slave 1024mb 512mb 120" 不够,旧连接仍按老规则跑:
- 执行
CONFIG REWRITE,把新值写进redis.conf,否则重启就回退到默认 - 用
CONFIG GET client-output-buffer-limit确认主节点已加载新配置 - 对已存在的从库连接,必须执行
CLIENT KILL TYPE slave强制重连,让新缓冲策略生效
漏掉任意一步,你看到的 omem 还是会照常爆掉。
比调参更关键的链路优化点
参数只是兜底,真要稳住全量同步,得动链路:
- 启用
repl-diskless-sync yes:避免主节点先写磁盘再读取发送 RDB,直接 socket 发送,大幅减少缓冲区堆积风险 - 检查
repl-timeout是否过小:默认 60 秒,在 RDB 生成+传输耗时长时容易误判超时,建议设为 120~300 - 确认从节点部署位置:跨机房、跨云同步时,网络延迟和抖动会让
omem更易堆积,这种场景下光调 buffer 治标不治本
真正容易被忽略的是:omem 是每个从节点独立计算的。5 个从节点同时拉 RDB,主节点就要维护 5 份输出缓冲区——调参前务必确认从节点数量和拓扑结构。


















