游乐游手机版
首页/数据库/文章详情

Redis内存暴涨导致服务雪崩的排查与解决

时间:2026-07-17 19:08
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内存暴涨导致服务雪崩的问题解决

  • Redis Cluster 某节点内存使用率从 45% 飙到 95%
  • 多个核心服务的 Redis 请求大量超时(P99 从 5ms → 3000ms+)
  • 用户侧反馈“页面打不开”、“登录失败”

排查过程

排查过程是这样的:

步骤操作发现
1redis-cli INFO memoryused_memory_rss 从 12GB 跳到了 28GB
2MEMORY STATSvolatile-ttl 类内存占比极低,说明大部分 key 没有设置过期时间
3SLOWLOG GET 100大量 KEYS session 和 HGETALL 大 key 操作
4INFO 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 预留缓冲

长期加固

  1. Redis 使用规范加入 deploy checklist:所有 cache key 必须设置 TTL,否则 CR 拒绝
  2. 新增监控:keyspace 每分钟 key 数量增长率,超过 5%/min 触发告警
  3. maxmemory-policy 从 noeviction 改为 allkeys-lru,极端情况自动淘汰而非拒绝写入
  4. 集成测试增加“无 TTL key 检测”脚本

复盘总结

快速复盘一下,这次事故其实给我们敲了三记警钟:

  1. 缓存的本质是“临时”——不设 TTL 的缓存不是缓存,是定时冲击波
  2. 监控要盯增长趋势,而不只是绝对值:80M key 不是一秒爆的,是 3 天慢慢涨上去的,早该发现
  3. maxmemory-policy noeviction 在生产环境极其危险,除非你对每条数据都精确控制了容量,否则请用 allkeys-lru 或 volatile-lru
来源:https://www.jb51.net/database/367345766.htm
上一篇Navicat跨平台同步数据后主键自增值不一致原因 下一篇Ubuntu系统Redis安装步骤详解
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
MySQL千万级大表如何平滑DDL变更避免长时间锁表
数据库 · 2026-07-17

MySQL千万级大表如何平滑DDL变更避免长时间锁表

MySQL8 0 12+对末尾添加允许NULL且无默认值的字段支持INSTANT算法秒级完成,避免锁表与主从延迟。否则需用pt-osc或gh-ost,并注意触发器延迟、binlog格式需设置为行模式、主从延迟及连接池及时进行刷新,防止业务抖动与中断,确保稳定。

MySQL外键约束大批量导入数据性能影响原因
数据库 · 2026-07-17

MySQL外键约束大批量导入数据性能影响原因

MySQL中外键校验逐行进行,无法批量合并,每行插入均触发独立存在性检查、加锁与释放,高并发下IO和锁竞争指数级放大。需为外键字段创建高效索引,慎用ONDELETECASCADE,必要时将校验移至应用层。

SQL窗口函数统计连续登录天数的方法
数据库 · 2026-07-17

SQL窗口函数统计连续登录天数的方法

连续登录天数统计通过登录日期减去窗口函数ROW_NUMBER()行号构造恒定分组标识实现,需用DATEDIFF等适配数据库差异,筛选至少连续3天用户应在外层按user_id聚合取最大值判断,并注意联合索引避免全表排序。

Redis集群状态fail时用redis-cli修复槽位方法
数据库 · 2026-07-17

Redis集群状态fail时用redis-cli修复槽位方法

Redis集群状态cluster_state:fail的根源包括主节点宕机、网络故障或槽位未分配等。redis-cli--clusterfix仅适用于节点在线且通信正常时的槽位空缺场景,无法处理进程挂掉或网络问题。使用前需验证节点连接、数量及槽位分配状态,否则可能掩盖问题或导致数据永久丢失。fix无效时应检查日志、手动补节点或重建集群。

Oracle安装报错INS-13001环境不支持?命令行加参数忽略
数据库 · 2026-07-17

Oracle安装报错INS-13001环境不支持?命令行加参数忽略

在Windows高版本操作系统安装Oracle时,若遇INS-13001不支持环境报错,可通过命令行添加`-ignorePrereq`跳过所有系统检查,或以`-J "-Doracle install db validate supportedOSCheck=false "`禁用特定系统校验。需以管理员身份运行CMD,切勿双击setup exe,并确保主机名和IP