首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Redis 内存持续上涨排查:大 key、过期策略与碎片率实战

Redis 内存持续上涨排查:大 key、过期策略与碎片率实战

原创
作者头像
一只特立独行的兔先生
发布于 2026-10-17 10:41:09
发布于 2026-10-17 10:41:09
190
举报

背景

线上 Redis 的 used_memory 一路上涨、最终触发 maxmemory 淘汰或 OOM,是常见故障。本文给出一套从“看全局指标”到“定位具体 key”的排查流程,命令均为 Redis 原生命令,云上托管实例与自建实例通用(托管实例部分命令可能被限制,以控制台说明为准)。

1. 先看全局:内存到底花在哪

代码语言:bash
复制
redis-cli INFO memory

重点关注字段:

  • used_memory:Redis 分配器向系统申请的内存,即数据集及内部结构占用。
  • used_memory_rss:操作系统视角的常驻内存。
  • mem_fragmentation_ratio:rss / used_memory。明显大于 1.5 说明碎片较多;小于 1 说明发生了 swap,需要立即处理。
  • maxmemory、maxmemory_policy:上限与淘汰策略。策略为 noeviction 时写满会直接报错。
代码语言:bash
复制
redis-cli MEMORY DOCTOR
redis-cli MEMORY STATS

MEMORY DOCTOR 会给出可读的诊断建议,MEMORY STATS 可看到各类内部开销占比。

2. 找大 key

代码语言:bash
复制
redis-cli --bigkeys -i 0.1

--bigkeys 基于 SCAN,按类型输出最大的 key;-i 0.1 表示每次扫描间隔 0.1 秒,降低对线上的影响。Redis 4.0 及以上还可以直接查看单个 key 的内存:

代码语言:bash
复制
redis-cli MEMORY USAGE user:session:10086 SAMPLES 5

对 hash、list、set 等集合类型,SAMPLES 越大越准、越耗时。

处理大 key 的原则:

  • 拆分:把一个大 hash 按 id 取模拆成多个小 hash。
  • 异步删除:使用 UNLINK 代替 DEL,由后台线程释放内存,避免主线程阻塞。
  • 避免一次性 HGETALL、SMEMBERS 大集合,改用 HSCAN、SSCAN。

3. 检查过期策略是否生效

内存涨而 key 数量也涨,往往是 key 没设置 TTL。

代码语言:bash
复制
redis-cli INFO keyspace
# db0:keys=5230000,expires=12000,avg_ttl=3600000

keys 远大于 expires 说明大量 key 永不过期。可抽样检查:

代码语言:bash
复制
redis-cli --scan --pattern 'cache:*' | head -n 20 | xargs -I{} redis-cli TTL {}

返回 -1 即无过期时间。修复方式是在写入处统一带上过期时间,例如 SET key value EX 3600,不要先 SET 再 EXPIRE,两步之间失败会留下永久 key。

另外 Redis 采用“惰性删除 + 定期抽样删除”,过期 key 不会立刻释放;如果大量 key 在同一时刻过期,可以给 TTL 加随机抖动,避免集中过期造成的延迟尖刺。

4. 碎片率高怎么办

当 mem_fragmentation_ratio 长期偏高且 used_memory 并不大时,可以开启在线碎片整理(需要 Redis 使用 jemalloc 编译):

代码语言:bash
复制
redis-cli CONFIG SET activedefrag yes
redis-cli INFO memory | grep -E 'active_defrag|allocator_frag'

在线整理会占用一定 CPU,建议在低峰开启并观察延迟。如果碎片严重且可以接受主从切换,也可以通过重启从库、再切换的方式整理。

5. 持续监控与告警

  • 对 used_memory / maxmemory 设置分级告警(如 80%、90%)。
  • 监控 evicted_keys、expired_keys:evicted_keys 持续增长说明已经在淘汰数据。
  • 定期(例如每周)低峰跑一次 --bigkeys,把结果与上周对比。

排查清单

  1. INFO memory 看 used_memory、碎片率、maxmemory_policy。
  2. INFO keyspace 对比 keys 与 expires。
  3. --bigkeys / MEMORY USAGE 定位大 key,拆分并改用 UNLINK。
  4. 写入统一带 TTL,并加随机抖动。
  5. 碎片率高时评估 activedefrag。
  6. 建立内存水位与淘汰数告警。

内存问题很少是单一原因,多数是“大 key + 无 TTL + 缺少监控”叠加。按上面顺序逐层排除,通常能在半小时内定位到根因。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 背景
  • 1. 先看全局:内存到底花在哪
  • 2. 找大 key
  • 3. 检查过期策略是否生效
  • 4. 碎片率高怎么办
  • 5. 持续监控与告警
  • 排查清单
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档