Redis中过期的key删除策略

353 阅读2分钟

这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战

一个Redis面试常见的面试题目:Redis中如果一个键过期了,那么它什么时候会被删除呢? 采用了什么策略呢?

一般策略

首先我们想想,如果交给我们自己,会怎么做?

  1. 定时器删除

    • 对每个key设置一个定时器,到时间的时候对其删除。
    • 这个方式的缺点很明显:每个key都有个定时器来保证key的过期状态,这十分消耗CPU。
  2. 定期删除

    • 在设置的一个小级别的周期,去扫描所有的key进行删除。
    • 这种方式挺好,但是还是不能保证缓存删除的及时性,存在周期时间窗口的延迟。
  3. 惰性删除

    • 我们不删除key,每次获取的时候判断是否过期,如果过期了就删除!
    • 这算是另辟蹊径了,方案也很不错,对CPU的消耗是最小的,只是会浪费部分内存。

Redis的方案

Redis对过期key的删除策略是采用了:惰性删除+定期删除 配合完成的:

  • 惰性删除:就是上述的惰性删除,在每次取key的时候判断key是否过期。

  • 定期删除:Redis会将那些设置了TTL的key放到一个单独的map中,然后定时遍历这个map进行删除。

    • 每次扫描是随机抽取,不能全扫!删除key的逻辑是主线程做的,不能阻塞用户请求,所以采用的方案是:少量多次!默认扫描时间不超过25ms,避免线程卡死
    • 扫描删除规则:10次/s,每次随机20个,删除其中过期的!如果过期的数量超过1/4,则再次循环。单次扫描时间最长25ms。
    • 因此,最好让过期时间随机点,不要在同一个时间过期,否则可能造成频繁扫描过期字典导致用户请求阻塞。