Redis 7.0 中配置内存淘汰策略本身不能防止OOM异常,它仅在maxmemory被突破后决定删谁;OOM错误仅在策略为noeviction时发生,此时Redis拒绝写入;真正防止OOM需设maxmemory并选用非noeviction策略。

Redis 7.0 中配置内存淘汰策略本身不能“防止”OOM异常,它只是在 maxmemory 被突破后决定“删谁”,而 OOM 异常(OOM command not allowed when used memory > 'maxmemory')只会在策略为 noeviction 时发生——此时 Redis 拒绝写入,把压力甩给上游。真正防止 OOM 的动作是:设 maxmemory + 选非 noeviction 策略。
必须先设 maxmemory,否则根本没机会触发淘汰
不设 maxmemory 或设为 0,Redis 在 64 位系统下会无限吃内存,直到被系统 OOM Killer 杀掉——这不是 Redis 报错,是进程直接消失。所以第一步永远是明确限制:
-
maxmemory 2gb✅(单位必须是kb/mb/gb,2g或2048m会被误解析) - 值建议设为物理内存的 75% 左右,为主从复制缓冲区、AOF 重写缓冲区留余量
- 切勿用
maxmemory 0上线生产环境
maxmemory-policy 不能选 noeviction,除非你真想让写请求失败
noeviction 是 Redis 7.0 默认策略,但它不是“安全模式”,而是“拒绝服务模式”。一旦内存打满,所有写命令(SET、HSET、LPUSH 等)立即返回 OOM command not allowed... 错误,容易引发上游重试风暴或业务降级。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 缓存场景一律禁用
noeviction;若必须保数据(如 Redis 当消息队列),则必须配监控+告警+人工干预流程 - 全键带 TTL(比如纯缓存)→ 优先
allkeys-lru或allkeys-lfu - 仅部分键带 TTL(如 session 有 EX,用户配置无过期)→ 必须用
volatile-lru,避免误删永久数据 - 绝对避开
volatile-ttl做通用缓存策略:TTL 集中设置(如批量预热设成 3600)会导致它在同一秒踢光一批 key,放大穿透
运行时改策略要快,但别信“切完就稳了”
线上告警时,CONFIG SET maxmemory-policy allkeys-lru 可立即生效,但它只影响后续写入行为,不会主动释放内存。此时必须配合“压内存”操作:
- 执行
MEMORY PURGE(Redis 7.0+ 支持):主动回收内存碎片,降低mem_fragmentation_ratio - 用
SCAN分批删冷 key:SCAN 0 MATCH tmp:* COUNT 500→ 拿到游标后DEL,避免阻塞 - 禁用
lazyfree-lazy-eviction yes(即保持默认no):确保淘汰动作同步完成,不堆积异步任务拖慢响应
容易被忽略的 AOF 重写放大效应
AOF 重写(BGREWRITEAOF)期间,子进程读取全量键 + 主线程持续写入 + 重写缓冲区增长,三者叠加极易让 used_memory_rss 突破 maxmemory。此时即使策略是 allkeys-lru,也会触发高频淘汰,CPU 拉高、延迟毛刺。
- 若
used_memory / maxmemory > 0.7,应立即将auto-aof-rewrite-percentage从默认 100 降至 60~80 - 不要关 AOF 重写(
auto-aof-rewrite-percentage 0):AOF 文件膨胀后,重启恢复时间不可控,且redis-check-aof修复失败率陡增 - 观察
INFO memory中evicted_keys是否在重写开始后突增,这是典型信号
最危险的组合是:没设 maxmemory + noeviction + 高频写入。这种配置上线等于埋雷——它不会立刻爆炸,但会在某次流量高峰或 AOF 重写时突然拒写,且毫无缓冲余地。

















