maxmemory=0时淘汰策略根本不会启动,因freeMemoryIfNeeded()判断被跳过;evicted_keys恒为0,监控失真;Redis持续写入直至OOM Killer介入,noeviction等策略形同虚设。

maxmemory=0 时淘汰策略压根不运行,不是失效,是根本没启动
maxmemory=0 意味着 Redis 完全不检查内存是否超限
淘汰策略(如 allkeys-lru、volatile-ttl)的触发前提是:Redis 在执行写命令前,调用 freeMemoryIfNeeded() 判断 used_memory >= maxmemory 是否成立。当 maxmemory 为 0 时,这个判断直接跳过——整个淘汰逻辑路径不会进入。
-
evicted_keys指标永远为 0,监控完全失真 - 即使配置了
volatile-lru,只要 key 没过期,它连“可淘汰池”都构不起来 - Redis 会持续接受写入,直到操作系统层面内存耗尽,触发 OOM Killer 杀进程
noeviction 策略在 maxmemory=0 下也形同虚设
很多人以为 noeviction 是“安全默认”,但它的作用域只在 maxmemory > 0 且内存触限时生效。一旦 maxmemory=0,noeviction 就像没写这行配置一样——既不拒绝写入,也不淘汰 key,纯靠系统兜底。
- 你看到的
CONFIG GET maxmemory-policy返回noeviction,不代表它正在工作 - 此时任何写命令(
SET、HSET、LPUSH)都会成功,直到malloc失败或被内核 kill - 容器环境更危险:
cgroup内存限制会被绕过,used_memory_rss超限后 pod 直接CrashLoopBackOff
为什么 INFO memory 里 used_memory 还在涨,但 evicted_keys 始终为 0?
因为 evicted_keys 只统计由淘汰策略主动删掉的 key 数量。而 maxmemory=0 时:
- 过期 key 的清理走的是另一条路径(
activeExpireCycle),计入expired_keys,和evicted_keys无关 - 没有淘汰发生,所以
evicted_keys永远是 0,哪怕used_memory已经飙到 20GB - 你监控告警如果只盯
evicted_keys > 0,那等于完全漏掉了这个最危险的失控状态
真正要警惕的不是“策略选错”,而是 maxmemory 这个开关根本没打开。它才是淘汰机制的总闸门,其他所有策略参数都依赖它通电才有效。生产环境里,maxmemory=0 和没配 maxmemory-policy 是两个独立的致命错误,必须同时确认。











