Redis默认noeviction策略会直接拒绝写入而非淘汰数据,其行为是硬性熔断;若内存达maxmemory后无淘汰,首要检查CONFIG GET maxmemory-policy是否为noeviction,或volatile-*类策略因key未设TTL而失效,再验证INFO memory中evicted_keys是否增长。

Redis 达到 maxmemory 后没淘汰数据,大概率不是“机制失灵”,而是淘汰策略根本没生效——它压根就没被触发,或者被配置成了不淘汰的模式。
检查 maxmemory-policy 是否为 noeviction
这是最常见原因。默认值就是 noeviction,它的行为非常明确:内存一超限,所有会增大内存的写命令(SET、HSET、LPUSH 等)直接返回错误 (error) OOM command not allowed when used memory > 'maxmemory',不做任何淘汰。
- 用
CONFIG GET maxmemory-policy确认当前值 - 如果返回
noeviction,说明你主动关掉了淘汰能力 - 切到可淘汰策略需显式设置,例如:
CONFIG SET maxmemory-policy allkeys-lru
确认策略类型与你的数据是否匹配
volatile-lru、volatile-lfu、volatile-ttl 这三类只作用于设置了过期时间的 key。如果你的数据全是永久 key(TTL 返回 -1),那这些策略就等于摆设——没一个 key 能进候选池,结果和 noeviction 效果一样。
- 执行
SCAN 0 COUNT 1000拿一批 key,再对每个 key 跑TTL查看返回值分布 - 若多数返回
-1,说明数据没设过期,volatile-*类策略必然失效 - 必须改用
allkeys-lru或allkeys-lfu才能覆盖全部 key
验证淘汰是否真在运行,别只看配置
配置写了不等于生效,得看指标有没有动。Redis 不会告诉你“我正在淘汰”,但会留下痕迹:
- 查
INFO memory,重点关注evicted_keys:该值为 0 或长期不增长,说明淘汰逻辑根本没触发 - 对比
used_memory_peak和used_memory:如果前者远高于后者,说明淘汰确实在腾空间;如果两者几乎相等,说明没释放过 - 注意
expired_keys是过期键清理计数,和淘汰无关,别混淆
真正容易被忽略的是:淘汰只响应写操作,且依赖采样(maxmemory-samples 默认 5),不是全量扫描。哪怕策略选对了,如果写入压力低、key 数量极大、或采样恰好没抽中可淘汰目标,也可能出现“看着内存满了却迟迟不淘汰”的假象。


















