Redis 采用了 两种策略相结合 的方法来删除过期键,以达到在合理使用 CPU 时间和避免浪费内存空间之间取得平衡。

这两种策略是:惰性删除定期删除

此外,当内存不足时,Redis 还会采用 主动删除(逐出) 策略。


惰性删除

这是默认的、在访问键时进行的删除策略。

  • 核心思想只有在访问一个键时,才会顺带检查它是否过期。如果过期,则立即删除。
  • 工作原理
    1. 当你执行 GETHGETLRANGE 等任何读写操作访问某个键时。
    2. Redis 会首先检查这个键是否设置了过期时间。
    3. 如果设置了,再检查当前时间是否大于该键的过期时间。
    4. 如果已过期,则立即删除这个键,并返回 nil(或空值),就像这个键不存在一样。如果未过期,则正常返回键值。
  • 优点
    • 对 CPU 友好:删除操作只会在访问键时发生,不会消耗额外的 CPU 时间去扫描大量可能永远不会被访问的过期键。
  • 缺点
    • 对内存不友好:如果一个键已经过期,但之后再也没有被访问,那么它将一直占用着内存空间,成为僵尸键。这可以看作是一种内存泄漏。

为了解决惰性删除的缺点,Redis 还需要另一种策略来配合。


定期删除

这是一种主动的、周期性的删除策略,用于补充惰性删除的不足。

  • 核心思想Redis 会定期地随机抽取一部分设置了过期时间的键,检查它们是否过期,并删除其中的过期键。
  • 工作原理
    1. 定时任务:Redis 将一个定时任务 (serverCron) 设置为每秒钟运行 10 次(默认配置,可通过 hz 调整)。
    2. 抽取样本:每次任务运行时,会从设置了过期时间的键的字典中,随机抽取 一定数量的键(默认是 20 个)。
    3. 检查并删除:对这 20 个键逐一检查其过期时间,删除所有已过期的键。
    4. 循环与限制:如果本轮抽出的 20 个键中,过期键的比例超过 25%,则立即再抽取 20 个键,并重复删除过程。这个过程会一直持续,直到过期键的比例低于 25% 或者本次任务的总耗时达到一个预设的时间上限(默认 25 毫秒)为止,以防止无限循环阻塞主线程。
  • 优点
    • 通过限制执行时长和频率,减少了对 CPU 时间的影响。
    • 有效地清理了那些永不访问的过期键,释放了内存,弥补了惰性删除的不足。
  • 缺点
    • 难以确定删除操作的时长和频率。如果太频繁或执行时间太长,会浪费 CPU;如果太少或太短,又会和惰性删除一样,导致内存浪费。

内存不足时的主动删除(逐出策略)

上述两种策略是在正常情况下工作的。当内存使用达到 maxmemory 限制时,Redis 会触发内存逐出机制。这个机制会根据配置的 maxmemory-policy 来删除键,以释放空间给新的命令使用。

这些策略也会考虑键的过期情况,例如:

  • volatile-lru:从设置了过期时间的键中,淘汰最近最少使用的。
  • volatile-lfu:从设置了过期时间的键中,淘汰最不经常使用的键
  • volatile-ttl:从设置了过期时间的键中,淘汰存活时间最短的(即 TTL 最小的)。
  • volatile-random:从设置了过期时间的键中,随机淘汰。
  • allkeys-lru:从所有键中,淘汰最近最少使用的。
  • allkeys-lfu:从所有键中,淘汰最不经常使用的键。
  • allkeys-random:从所有键中,随机淘汰。
  • noeviction:不删除任何键,拒绝所有可能导致内存增加的写入命令(默认策略)。

可以看到,volatile-* 开头的策略会主动去检查并删除那些设置了过期时间的键(即使它们还没被定期删除任务清理掉),这可以看作是内存压力下的一种更积极的过期键删除行为。


总结

策略 触发时机 优点 缺点 角色
惰性删除 每次访问键时 对 CPU 友好,不浪费计算资源 对内存不友好,可能导致过期键长期存在 被动清理,第一道防线
定期删除 由 Redis 的定时任务周期性触发 弥补惰性删除不足,减少内存浪费 频率和时长需要权衡,否则影响 CPU 主动清理,第二道防线
主动删除 内存使用达到 maxmemory 保证系统在限定的内存下运行 可能会删除重要的键 紧急清理,最后一道防线

Redis 过期键删除的整体流程可以概括为:

  1. 防堆积:依靠定期删除,周期性、有限度地清理过期键,防止大量过期键堆积。
  2. 保即时:当访问到某个键时,惰性删除确保它能被立刻清理,保证数据一致性。
  3. 保生存:当内存不足时,主动删除(逐出) 策略强制清理键(优先清理过期键),保证 Redis 服务不会因内存耗尽而崩溃。

这三种机制相互配合,使得 Redis 能够高效地管理过期键。