Redis 过期 key 删除策略

一、Redis 的过期策略是什么

Redis 并没有采用「每个 key 到期就立刻删除」的方案,因为那样需要为每个 key 维护定时器,开销太大。它实际用的是两种策略配合:

1. 惰性删除(Lazy Deletion)

  • 当客户端访问某个 key 时,Redis 才会检查它是否过期。

  • 如果已过期,就删除并返回空。

  • 优点:对 CPU 友好,只在访问时才做检查。

  • 缺点:如果某个过期 key 一直不被访问,它会一直占着内存,造成内存泄漏。

2. 定期删除(Active/Periodic Deletion)

  • Redis 会周期性地主动扫描一部分设置了过期时间的 key,删除其中已过期的。

  • 这是对惰性删除的补充,防止过期 key 长期占用内存。

惰性删除保证访问时不会拿到过期数据,定期删除负责兜底清理,两者结合。

二、底层实现:过期字典 + 定期删除的具体逻辑

过期字典(expires dict)

  • Redis 每个数据库(redisDb)里有一个 expires 字典,专门存放「设置了过期时间的 key」和它的到期时间戳。

  • 注意:只有设置了 TTL 的 key 才会进这个字典,没设过期时间的 key 不在这里。

定期删除的执行细节

Redis 默认每秒执行 10 次(hz 配置,默认 10)过期扫描,每次的逻辑大致是:

  1. 从过期字典中随机抽取 20 个 key;

  2. 删除其中已过期的 key;

  3. 如果这 20 个里有超过 10%是过期的,说明过期 key 比例还很高,就再抽 20 个继续删;(“这个阈值取决于 Redis 版本。在较老的版本里是 25%,而 Redis 7.0 之后,默认调低到了 10%,意味着清理行为会变得更积极一些。”)

  4. 重复直到过期比例低于 10%,或者本轮扫描时间超过 25ms(防止阻塞主线程)。

其中有几个重要参数:

1、定期删除的频率(hz参数):z 默认为 10,代表每秒执行 10 次,也就是每秒钟进行 10 次尝试来查找并删除过期的 key。 hz 的取值范围为 1~500。增大 hz 参数的值会提升定期删除的频率。如果你想要更频繁地执行定期删除任务,可以适当增加 hz 的值,但这会增加 CPU 的使用率。根据 Redis 官方建议,hz 的值不建议超过 100,对于大部分用户使用默认的 10 就足够了。

2、每次随机抽查的数量: Redis 7.2 版本为 20,也就是说每次会随机选择 20 个设置了过期时间的 key 判断是否过期。

3、执行时间阈值:执行时间已经超过了阈值,那么就中断这一次定期删除循环,以避免使用过多的 CPU 时间。

4、过期 key 比例:如果这一批过期的 key 比例超过一个比例,就会重复执行此删除流程,以更积极地清理过期 key。相应地,如果过期的 key 比例低于这个比例,就会中断这一次定期删除循环,避免做过多的工作而获得很少的内存回收。

这里的关键点:

  • 随机抽样而不是全量扫描,是为了控制 CPU 占用;

  • 10% 阈值 + 时间上限,是为了在「清理干净」和「不阻塞」之间做平衡;

  • Redis 是单线程处理命令的,所以定期删除必须严格限时,否则会卡住正常请求。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值