首页 > Technology > 正文

Redis 内存满了怎么办?OOM 时的应急止损与长期治理

fenij 2026-08-11 46 Technology

Redis 是个内存数据库,快是快,但内存满了就是硬墙。一旦触发 (error) OOM command not allowed when used memory > 'maxmemory',写操作全停,业务立刻受影响。下面这套流程分「先保命、再定位、后根治」,按分钟级响应来设计。

第一分钟:看清现场

连上 Redis 后先抓三个指标:

redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human|mem_fragmentation_ratio"
redis-cli CONFIG GET maxmemory-policy
redis-cli INFO stats | grep evicted_keys

如果 maxmemory-policynoeviction,那满了就会直接拒写。如果是 allkeys-lru,Redis 会自己踢老 key,但也会增加时延抖动。

第二分钟:马上止损

业务不能等排查,先做三件事:

  1. 临时扩容:redis-cli CONFIG SET maxmemory 4gb,前提是宿主机还有余量。
  2. 开淘汰策略:redis-cli CONFIG SET maxmemory-policy allkeys-lru,让冷数据自动出去。
  3. 清大 key:用 UNLINK 代替 DEL,异步删除不阻塞。
redis-cli --bigkeys
redis-cli UNLINK session:bulk:list temp:cache:batch

第三分钟:找出内存大户

盲目扩容只是拖延,得知道谁在吃内存。推荐两条命令:

redis-cli --bigkeys
redis-cli MEMORY DOCTOR

常见元凶有三类:单个超大 String(比如 500 MB 的 JSON)、成员数爆炸的 ZSET/HASH、没设 TTL 的临时缓存。

🔑
TTL
所有缓存都要设过期
📊
80%
内存告警阈值
🧹
UNLINK
比 DEL 更安全的删除

长期治理:别让 OOM 再来

临时调整要落进配置文件,否则重启就丢:

maxmemory 4gb
maxmemory-policy allkeys-lru
activedefrag yes

另外几个习惯能避免大部分内存事故:

  • 所有缓存 key 必须带 TTL,业务 key 按生命周期分级。
  • 大 HASH/ZSET 按业务维度拆小,单 key 成员数别过百万。
  • 监控 used_memory / maxmemory,80% 就告警。
  • Redis 只放热数据,冷数据归档到持久化数据库。

淘汰策略怎么选

策略 行为 适用场景
noeviction 写操作直接报错 关键数据,不能丢
allkeys-lru 踢最近最少用 通用缓存,最常用
volatile-ttl 优先踢快过期的 带 TTL 的业务数据
allkeys-lfu 踢访问频率最低 访问差异大的缓存

常见问题

Q:能不能直接关掉 maxmemory 限制?
A:生产环境不建议。Redis 吃光内存后会被 Linux OOM Killer 直接杀掉,反而全挂。宁可设合理上限加淘汰策略。

Q:mem_fragmentation_ratio 大于 1.5 怎么办?
A:说明内存碎片高。Redis 4.0+ 可以在线开 active defrag:CONFIG SET activedefrag yes

Q:集群版 Redis 也会单分片 OOM 吗?
A:会。这叫内存倾斜,某个 key 过大或 hash tag 设计不当会让某个分片先满。需要按 key 重新分片或拆分大 key。

你的 Redis 有没有因为某个大 key 半夜报警?欢迎在 fenij.com 留言,把踩过的坑分享出来。

排错自查清单

  • ☐ 第一分钟:看清现场:连上 Redis 后先抓三个指标:
  • ☐ 第二分钟:马上止损:业务不能等排查,先做三件事:
  • ☐ 第三分钟:找出内存大户:盲目扩容只是拖延,得知道谁在吃内存。推荐两条命令:
  • ☐ 长期治理:别让 OOM 再来:临时调整要落进配置文件,否则重启就丢:
  • ☐ 淘汰策略怎么选
  • ☐ 常见问题:Q:能不能直接关掉 maxmemory 限制? A:生产环境不建议。Redis 吃光内存后会被 Linux O

关键命令速查

  • redis-cli INFO memory | grep -E "used_memory_human|maxmemory_human|mem_fragmentation_ratio
  • redis-cli --bigkeys redis-cli UNLINK session:bulk:list temp:cache:batch
  • redis-cli --bigkeys redis-cli MEMORY DOCTOR
  • maxmemory 4gb maxmemory-policy allkeys-lru activedefrag yes

相关延伸

更系统的排查思路,见 Technology 分类归档

补充:Redis 爆内存先别急着加机器:用 redis-cli --bigkeys 找出大 key,再决定淘汰策略。纯缓存用 allkeys-lru,会话类用 volatile-lru 并设 TTL。注意 AOF 重写本身也吃内存,尽量避开业务高峰;用了驱逐策略还频繁 OOM,多半是有 key 忘了设过期时间。线上务必设 maxmemory 上限并配告警,用 INFO memory 观察碎片率,碎片高时重启实例比硬撑更干净,别等到把宿主拖垮。

相关完整手册

系统化的排查与配置思路,建议顺手收藏这几篇完整手册: