广告广告位招商联系 ads@iiunion.comA5 · 728×90(移动端 320×100) · 参考价 ¥300/月了解详情 →

Redis 内存持续上涨?bigkey 排查与逐出策略配置

Started by Internet_Notes · 2026-10-22 01:35 UTC · 9 views · 2 replies
I Member
线上 Redis 内存一直在涨,重启又不敢随便重启。分享排查思路。

一、确认是不是 bigkey
1. redis-cli --bigkeys 扫一遍,看最大的 key 有多大。
2. 更精细的:用 SCAN + MEMORY USAGE 抽样统计,别在高峰期全量扫。
3. 常见元凶:没设过期时间的缓存 key、越积越多的 list/set、存了超大 JSON 的 string。

二、处理 bigkey
1. 大 string:拆分成 hash 结构,按字段存取。
2. 大 list/set:按时间或业务维度拆 key。
3. 删除 bigkey 别直接 DEL,会阻塞——用 UNLINK 异步删除。

三、逐出策略(maxmemory-policy)
1. 纯缓存场景:allkeys-lru 最常用。
2. 有持久化数据混部:volatile-lru,只淘汰设了过期时间的。
3. 别用 noeviction 当默认,写满了直接报错,半夜被告警叫醒的就是你。
4. maxmemory 要留余量,给复制 buffer 和碎片留空间。

四、长效建议
1. 所有缓存 key 强制过期时间,code review 卡这一条。
2. 监控内存使用率和 key 数量趋势,告警阈值设 70% 而不是 90%。
3. 定期 review:业务下线了,key 还在涨吗?

你们线上 Redis 出过最大的事故是什么?bigkey 还是逐出策略配错了?
I Editorial
思路很完整,补充几点生产中的经验。一是先看 INFO memory 里的 used_memory 和 used_memory_rss 以及 mem_fragmentation_ratio,如果碎片率明显大于 1.5,内存上涨可能是碎片而不是数据增长,4.0 以上可以开启 activedefrag 在线整理。二是别漏了非数据内存:大量客户端连接的输出缓冲区(尤其是 pub/sub 订阅者和慢消费者)、复制积压缓冲区、Lua 脚本缓存都会占内存,CLIENT LIST 里看 omem 字段能发现异常客户端。三是 --bigkeys 只按元素个数排序,对 hash/list 不一定反映实际字节数,新版本可以用 --memkeys 按 MEMORY USAGE 统计。另外 lazyfree-lazy-eviction 和 lazyfree-lazy-expire 打开后,逐出和过期删除大 key 也会走异步,减少阻塞。
I Member
碎片这条再展开一下:activedefrag 开起来是有 CPU 代价的,defrag-cycle-min/max 可以按业务低高峰调整,低峰期开大一点;碎片率居高不下时可以看 MEMORY MALLOC-STATS 里 jemalloc 的 arena 分布,确认是分配器层面碎片而非数据膨胀,避免误判。

慢消费者这点很关键,我们还吃过一个亏:有人在线上开了 MONITOR 排查问题忘了关,输出缓冲区把内存吃光了。MONITOR 之后最好配 client-output-buffer-limit 做熔断,pub/sub 场景也一样,订阅端消费跟不上就先断开保服务端。

另外 bigkey 排查如果不敢在线上扫,可以把 RDB 拷下来离线分析(按字节数排序的工具很多),对生产零影响。lazyfree 开了之后别忘了监控 lazyfree_pending_objects,异步释放队列堆积时也会短暂占着内存,别看到内存没立刻降下来就慌。
广告广告位招商联系 ads@iiunion.comA6 · 728×90(移动端 320×100) · 参考价 ¥200/月了解详情 →
Log in or register to reply.