根本原因是client-output-buffer-limit slave配置过小,导致主节点在rdb传输或命令积压时频繁断连重连,缓冲区内存无法及时释放而叠加,最终oom;应设为“1024mb 256mb 120”并同步调大repl-backlog-size至1024mb。

Redis主从同步时出现OOM,根本原因不是内存不够,而是client-output-buffer-limit slave配置过小,导致主节点在传输RDB或积压命令时主动断连,触发重连—堆积—再断连的恶性循环,最终压垮内存。
为什么调小client-output-buffer-limit slave反而会OOM
很多人误以为“限制越严越安全”,但实际中:client-output-buffer-limit slave设得太小,会让主节点在RDB传输中途或增量追赶阶段就强制关闭从节点连接。而断连前已分配的输出缓冲区内存不会立刻释放,新连接又马上建立并重试同步,多个从节点反复重连就会叠加内存占用。
典型现象包括:
-
OOM command not allowed when used memory > 'maxmemory'频繁报错,但INFO memory显示used_memory_rss远高于used_memory -
CLIENT LIST中大量omem值超过 100MB 的连接,且cmd=psync或为空 - 日志持续刷出
scheduled to be closed ASAP for overcoming of output buffer limits
怎么设才合理:三参数含义与推荐值
client-output-buffer-limit slave <hardlimit><softlimit><softseconds></softseconds></softlimit></hardlimit> 不是随便放大就行,三个参数必须协同考虑:
-
hardlimit:硬上限,一旦omem超过该值,立即断连 —— 生产建议设为1024mb或0(0 表示不限制,慎用) -
softlimit:软上限,比如256mb,表示允许短暂冲高 -
softseconds:软上限持续时间,比如120秒,超时才断连 —— 比默认60更宽松,给从节点加载RDB留足时间
实操命令示例(立即生效):
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
config set client-output-buffer-limit "slave 1073741824 268435456 120"
对应配置文件写法:
client-output-buffer-limit slave 1024mb 256mb 120
必须同步调整的配套配置
只改 client-output-buffer-limit 不够,它和 repl-backlog-size 是一对搭档:
- 如果
repl-backlog-size太小(默认仅1mb),从节点一断就连不上,立刻退化全量同步 → 又要进client-output-buffer-limit的坑 - 建议按「峰值写入带宽 × 断连容忍时长」估算,例如写入峰值 5MB/s、容忍断连 120 秒,则至少设为
600mb,生产环境可起步设1024mb - 配套执行:
config set repl-backlog-size 1073741824
并确认写入redis.conf
容易被忽略的隐性瓶颈
即使 buffer 配够了,OOM 还可能发生——这时候要看真实瓶颈在哪:
- 主从跨机房部署?RTT 高 + 带宽窄 → RDB 传一半就超
repl-timeout(默认 60 秒),照样断连重试 - 从节点开了
appendonly yes且appendfsync always?命令重放速度跟不上,omem就一直涨 - 主节点
save策略太激进?频繁bgsave导致 fork 延迟高,复制缓冲区堆积更快
真正稳定的主从同步,从来不只是调一个参数的事;buffer 是闸门,但水压(写入)、流速(网络)、下游排水能力(从节点执行效率)都得一起看。










