Redis过期了,内存为何还滞留?这正常吗?

2026-10-10 21:350阅读0评论建站教程
  • 内容介绍
  • 文章标签
  • 相关推荐

凌晨两点半的告警把我从床上拽起来 监控面板上 Redis 的 used_memory 一直在迟缓攀升,却死活降不下来。明明业务日志里体现一较大批 key 早就该过期了按理说内存应当回落,最终还是结果是曲线像一条倔强较大的直线往上走。我盯着屏幕看了五分钟, 手心启动出汗,第一反应是:是不是有人把 TTL 写错了还是我们被内存泄漏给坑了?那种明明了解数据该消失却赖着不走的感觉,比直接 OOM 还让人焦虑,至于吗?。

过期只是标记, 不是立刻清场

先沉着下来喝口水,把 Redis 的过期机制捋一遍。其实很更多同学的第一印象就是:TTL 到点了数据就立刻从内存里蒸发。但真实实情况要温柔得更多,也更残酷得更多。Redis 并不会在 key 到期那一刻就真实的去删除它,它只是在 key 上打一个“已过期”的较小标签。一直躺在那里占着地方,哈基米!。

Redis 过期了为什么内存还在?——Redis系列(十)

一阵见血。 这种设计叫做惰性删除,听起来很懒,其实是为了性能。你想啊, 如果有几百万个 key 同时也到期,Redis 要是一股脑全部清理掉,主线程会被卡住几秒钟,那线上申请岂不是全挂了。所以它选择偷懒,等你来用的时候再顺手扔掉。这种偷懒换来了较高并发下的平稳,也带来了我们看到的内存滞留现象。说白了不是内存较差了是 Redis 在装死。

还有个更积极的保洁员

当然 Redis 也不是彻底不管。它有后台的一个较小进程叫 active expire, 会定期随机抽样一批带 TTL 的 key 来检查有没有过期,然后主动删掉一一部分。当前这个策略叫主动过期,又称定期抽样清理。但抽样的比例和次数是有约束的,默认每秒会做十次每次检查二十个 key。听起来挺勤迅速, 但如果你的过期 key 量特别较大,或者集中在一个时间段段爆发,当前这个频率就显得像用勺子舀海水。于是较更多的已过期 key 就堆积在内存里形成我们看到的“滞留”。

我当时查了一下 info memory, 发觉瞬时内存占用比实际有效数据更多了将近 40%,心里那个地方的火啊,想把运维群里的消息一条条撤回。

阅读全文

凌晨两点半的告警把我从床上拽起来 监控面板上 Redis 的 used_memory 一直在迟缓攀升,却死活降不下来。明明业务日志里体现一较大批 key 早就该过期了按理说内存应当回落,最终还是结果是曲线像一条倔强较大的直线往上走。我盯着屏幕看了五分钟, 手心启动出汗,第一反应是:是不是有人把 TTL 写错了还是我们被内存泄漏给坑了?那种明明了解数据该消失却赖着不走的感觉,比直接 OOM 还让人焦虑,至于吗?。

过期只是标记, 不是立刻清场

先沉着下来喝口水,把 Redis 的过期机制捋一遍。其实很更多同学的第一印象就是:TTL 到点了数据就立刻从内存里蒸发。但真实实情况要温柔得更多,也更残酷得更多。Redis 并不会在 key 到期那一刻就真实的去删除它,它只是在 key 上打一个“已过期”的较小标签。一直躺在那里占着地方,哈基米!。

Redis 过期了为什么内存还在?——Redis系列(十)

一阵见血。 这种设计叫做惰性删除,听起来很懒,其实是为了性能。你想啊, 如果有几百万个 key 同时也到期,Redis 要是一股脑全部清理掉,主线程会被卡住几秒钟,那线上申请岂不是全挂了。所以它选择偷懒,等你来用的时候再顺手扔掉。这种偷懒换来了较高并发下的平稳,也带来了我们看到的内存滞留现象。说白了不是内存较差了是 Redis 在装死。

还有个更积极的保洁员

当然 Redis 也不是彻底不管。它有后台的一个较小进程叫 active expire, 会定期随机抽样一批带 TTL 的 key 来检查有没有过期,然后主动删掉一一部分。当前这个策略叫主动过期,又称定期抽样清理。但抽样的比例和次数是有约束的,默认每秒会做十次每次检查二十个 key。听起来挺勤迅速, 但如果你的过期 key 量特别较大,或者集中在一个时间段段爆发,当前这个频率就显得像用勺子舀海水。于是较更多的已过期 key 就堆积在内存里形成我们看到的“滞留”。

我当时查了一下 info memory, 发觉瞬时内存占用比实际有效数据更多了将近 40%,心里那个地方的火啊,想把运维群里的消息一条条撤回。

阅读全文