必须同时设置maxmemory和maxmemory-policy noeviction,缺一或拼写错误(如NoEviction、no-eviction)会导致Redis退回到默认行为,不触发淘汰,内存持续增长直至被系统OOM Killer杀死。

怎么确认是没配淘汰策略导致的OOM
直接执行 redis-cli CONFIG GET maxmemory-policy,如果返回值不是 noeviction(全小写、无空格、无拼写错误),或者压根返回空,那基本就是它了。尤其注意大小写混用(如 NoEviction)、带连字符(no-eviction)、多空格等写法,Redis 一律不认——它会悄悄退回到版本默认行为,而高版本默认虽是 noeviction,但你没显式声明,就等于把控制权交给了运气。
再补一刀验证:redis-cli INFO memory | grep used_memory 和 CONFIG GET maxmemory 对比,如果 used_memory 已逼近甚至等于 maxmemory,且 evicted_keys 始终为 0,说明 Redis 根本没启动任何淘汰逻辑,纯靠拒绝写入硬扛。
为什么只设maxmemory却不管用
maxmemory 不是保险丝,只是个“水位标尺”。它只在淘汰策略生效的前提下才起作用;没配对的 maxmemory-policy,Redis 就不会拿这个水位去判断要不要驱逐或拒绝——它会继续接收写命令,直到 RSS 内存爆满,触发系统级 OOM Killer 直接杀进程。
- 常见误操作:配置文件里写了
maxmemory 2gb,但漏了maxmemory-policy行,或写成maxmemory_policy noeviction(下划线错) - 危险信号:
redis-cli --stat中mem列卡在maxmemory附近不动,新SET或PUBLISH全报(error) OOM command not allowed when used memory > 'maxmemory' - 别信“默认就是 noeviction”:6.0+ 版本虽默认如此,但 ACL 用户若没
+config权限,CONFIG GET可能根本查不到,你以为配了,其实没生效
怎么快速救急并落盘生效
先临时放开限制,让服务恢复,再立刻固化配置:
- 执行
redis-cli CONFIG SET maxmemory-policy allkeys-lru(或按业务选volatile-lru),立刻启用淘汰 - 紧接着
redis-cli CONFIG SET maxmemory 2gb(确保单位正确,2g可,2gb报错) - 马上执行
redis-cli CONFIG REWRITE,它会把这两项写进redis.conf,保留原有注释和结构 - 重启前务必
redis-cli SHUTDOWN SAVE,避免配置未落盘 + 数据丢失 - 重启后立刻验证:
CONFIG GET maxmemory和CONFIG GET maxmemory-policy必须双双返回预期值
容易被忽略的缓冲区陷阱
即使你配对了 maxmemory 和 maxmemory-policy,仍可能因客户端输出缓冲区撑爆而报同样错误——因为 maxmemory 不管这部分内存。
检查 redis-cli INFO clients 中的 client_longest_output_list 和 omem 字段,若长期 >1MB,说明有 client 没读响应;再查 CONFIG GET client-output-buffer-limit,特别是 normal 类型,压测或 Pub/Sub 场景下默认的 0 0 0(无限制)反而危险,建议设为 normal 512mb 128mb 60(硬限 512MB,软限 128MB 持续 60 秒则断连)。
真正麻烦的是:这类缓冲区溢出不会增加 evicted_keys,也不会触发淘汰策略,但一样报 OOM command not allowed——它骗过了你的第一层排查逻辑。











