Redis内存暴涨导致服务雪崩的排查与解决
Redis集群某节点内存从45%飙升至95%,导致服务P99延迟从5ms升至3000ms以上,用户页面打不开、登录失败。根因是新上线session缓存未设置TTL,配合运营活动三天积累8000万永久key,且maxmemory-policy为noeviction。通过Lua脚本删除空闲key、设置1小时TTL、改为allkeys-lru策略解决。
问题现象
凌晨三点,告警声像闹钟一样准时响起。Redis 集群里某个节点,内存使用率从 45% 一路飙升到 95%,几乎涨了一倍。紧接着,多个核心服务的请求开始大面积超时——P99 从原本的 5ms 直接跳到 3000ms 以上。用户侧那边,反馈已经炸了:页面打不开、登录失败……一句话,典型的雪崩前兆。

- Redis Cluster 某节点内存使用率从 45% 飙到 95%
- 多个核心服务的 Redis 请求大量超时(P99 从 5ms → 3000ms+)
- 用户侧反馈“页面打不开”、“登录失败”
排查过程
排查过程是这样的:
| 步骤 | 操作 | 发现 |
|---|---|---|
| 1 | redis-cli INFO memory | used_memory_rss 从 12GB 跳到了 28GB |
| 2 | MEMORY STATS | volatile-ttl 类内存占比极低,说明大部分 key 没有设置过期时间 |
| 3 | SLOWLOG GET 100 | 大量 KEYS session 和 HGETALL 大 key 操作 |
| 4 | INFO keyspace | 某个 db 里 key 数量 8000万+,几乎是上周的 10 倍 |
| 5 | 查发布记录 | 3 天前新上线了一个功能,把用户 session 缓存到了 Redis |
罪魁祸首浮出水面:新上线的 session 缓存逻辑。
根因
问题出在哪儿?新功能的代码长这样:
redis.set("session:" + userId, sessionData)忘了写 EX(过期时间)。
加上当天正好有一波运营活动流量,短短 3 天积累了近 8000 万个永久有效的 session key。Redis 的 maxmemory-policy 配置的是 noeviction(不淘汰),内存满了之后直接拒绝所有写请求 → 连锁反应导致读也阻塞 → 服务超时 → 雪崩。
一句话总结:忘记设置 TTL 的缓存 = 内存泄露冲击波。
解决方案
止血(5分钟内)
- Lua 脚本批量扫描 session key,对 idletime > 1800 的 key 执行 UNLINK 异步删除
- 内存迅速回落至 55%
短期修复(当天)
- 紧急 hotfix:所有 session 写入加上 EX 3600(1小时 TTL)
- 临时调大 maxmemory 预留缓冲
长期加固
- Redis 使用规范加入 deploy checklist:所有 cache key 必须设置 TTL,否则 CR 拒绝
- 新增监控:keyspace 每分钟 key 数量增长率,超过 5%/min 触发告警
- maxmemory-policy 从 noeviction 改为 allkeys-lru,极端情况自动淘汰而非拒绝写入
- 集成测试增加“无 TTL key 检测”脚本
复盘总结
快速复盘一下,这次事故其实给我们敲了三记警钟:
- 缓存的本质是“临时”——不设 TTL 的缓存不是缓存,是定时冲击波
- 监控要盯增长趋势,而不只是绝对值:80M key 不是一秒爆的,是 3 天慢慢涨上去的,早该发现
- maxmemory-policy noeviction 在生产环境极其危险,除非你对每条数据都精确控制了容量,否则请用 allkeys-lru 或 volatile-lru
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
SQL数据库视图简化开发人员编码的实用方法
视图适合封装固定逻辑(如固定时间窗口、静态状态过滤)和固定JOIN关系,不宜用于需动态传入参数(如用户ID、日期范围)的查询。视图性能取决于底层索引,而非视图本身。ALTERVIEW仅更新元数据,会短暂阻塞新查询启动,应避开高峰期操作。
MySQL decimal使用常见问题及解决方法
MySQL中的DECIMAL类型用于精确数值计算,通过DECIMAL(M,D)定义精度与标度。常见问题包括精度设置不当导致溢出、计算时精度溢出、插入格式错误等。优化建议:合理设置M和D,可用BIGINT存储分单位,关键列建索引,保持版本更新。
MySQL大字段TEXT建立索引导致的性能下降解决方案
TEXT字段无法直接建立常规B+树索引,前缀索引不支持左模糊查询,全文索引受词长、中文分词和更新延迟限制。高效替代方案是使用MD5摘要索引和垂直拆分,将TEXT字段分离到独立表,主表采用DYNAMIC行格式,避免溢出页IO问题。
金仓数据库迁移避坑指南:从未被质疑的左连接隐患
迁移至金仓KES时,LEFTJOIN若在WHERE中过滤右表非空列,将会触发外连接消除,导致数据结果减少。正确做法是将过滤条件置于ON子句中。金仓KES与主流数据库行为一致,务必通过EXPLAIN仔细检查执行计划,以确保连接语义正确。
PostgreSQL与MySQL数据库日志机制深度对比
PostgreSQL仅使用一套WAL日志,就同时实现了MySQL的redo、binlog和undo的全部功能,而MySQL因插件式架构需要三套日志并依赖两阶段提交保证一致性。其多版本并发控制通过追加写实现,无需单独的undo日志,但需要定期执行VACUUM操作清理死元组,防止表膨胀。
- 热门数据榜
相关攻略
2026-07-18 22:24
2026-07-18 22:22
2026-07-18 22:22
2026-07-18 22:22
2026-07-18 22:22
2026-07-18 22:05
2026-07-18 22:05
2026-07-18 22:05
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

