Redis主节点OOM根本原因是client-output-buffer-limit slave配置过小,导致从节点断连重试时输出缓冲区内存反复堆积无法释放,需设为“1024mb 256mb 120”并同步调大repl-backlog-size至1024mb。

Redis从节点本身不会触发OOM,但主节点会因从节点同步行为间接OOM——根本原因在client-output-buffer-limit slave配置不当,不是内存真不够,而是缓冲区反复堆积失控。
为什么从节点同步会导致主节点OOM
主节点为每个从节点维护一个输出缓冲区(output buffer),用于暂存待发送的RDB数据或增量命令。一旦这个缓冲区被填满且无法及时清空,主节点就会强制断开该从节点连接。但关键点在于:断连不等于释放内存——已分配的缓冲区内存不会立刻归还,而从节点几乎马上重连、重试同步,新缓冲区又分配出来,多个连接反复叠加,omem值持续飙升,最终压垮主节点RSS内存。
典型现象包括:
-
OOM command not allowed when used memory > 'maxmemory'报错,但INFO memory显示used_memory远低于maxmemory -
CLIENT LIST中大量连接的omem值超过 100MB,cmd字段为psync或为空 - 日志持续出现
scheduled to be closed ASAP for overcoming of output buffer limits
必须调优的两个核心配置
client-output-buffer-limit slave 和 repl-backlog-size 是一对强耦合参数,单改其一无效。
client-output-buffer-limit slave 三参数含义与推荐值:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
hardlimit:硬上限,超即断连;生产建议设为1024mb(1GB),或0(不限制,慎用) -
softlimit:软上限,如256mb,允许短暂冲高 -
softseconds:软上限持续时间,如120秒,给从节点加载RDB留足时间,比默认60更合理
立即生效命令:
config set client-output-buffer-limit "slave 1073741824 268435456 120"
repl-backlog-size 必须同步放大,否则从节点断连后无法增量恢复,被迫全量重同步 → 又一次压入大缓冲区。估算公式:峰值写入带宽 × 断连容忍时长。例如写入峰值 5MB/s、容忍断连 120 秒,则至少设为 600mb,生产环境起步设 1024mb:
config set repl-backlog-size 1073741824
容易被忽略的隐性瓶颈
即使上述两项调优完成,仍可能OOM,因为:
-
maxmemory没和容器limits.memory对齐:Kubernetes 中若只设limits.memory: 2Gi却没显式设maxmemory 1536mb,Redis 会无视 cgroup 限制,fork RDB 时瞬间翻倍内存,直接被 OOM Killer 杀掉 -
activedefrag关闭或参数过严:碎片率mem_fragmentation_ratio > 1.5时,若active-defrag-threshold-lower设为15而实际只有14,就不会触发整理,长期运行下小碎片累积成大压力 - 淘汰策略选
noeviction:内存满后拒绝写入,但客户端若持续重试、堆积请求,会进一步撑大输出缓冲区,形成恶性循环
真正卡住问题的,往往不是单个参数值,而是client-output-buffer-limit、repl-backlog-size、maxmemory、maxmemory-policy 四者之间的节奏失配——调参不是填数字,是让它们在RDB传输、增量追赶、断连恢复、内存回收这几个阶段彼此“踩得上点”。

















