原创

Redis的过期和淘汰是两回事儿

本文字数:

2346

,大约阅读2分钟

做程序员的竞争越来越大,有一种三百六十行,行行转程序员的感觉。当程序员的想着转行做送外卖逃离 007、996,送外卖的却想着转行当程序员。看到群里小伙伴发的照片,想起以前一个阿姨在地铁上学 Java Web 的照片,真的是太卷了……不,是太励志了!

今天整理一下关于 Redis 的过期策略和淘汰机制,这两个东西看着很像,其实不是一回事儿。

一、过期策略

我们在使用 Redis 当作缓存时,通常会给 Redis 的 Key 设置一个过期时间,被设置过期时间的 Key 在未过期时可以对其进行读取或更新操作,也可以主动将其删除。当其超过设置的时间后,它将失效。通过它的过期机制,可以完成很多功能,比如计数器复位、token 过期等。

那么,Redis 对已经过期的数据是进行如何处理,或者说是如何删除呢?在 Redis 中有两种策略来删除过期的 Key,分别是 主动删除和 被动删除 两种方式,也有资料称为 定期删除 和 惰性删除。

被动删除(惰性删除)

被动删除也被称为惰性删除,是 Redis 中的 Key 已经过期,但是 Redis 不会主动将其删除,当有客户端访问该过期 Key 时,Redis 对其进行检查,发现其过期则将其删除,并返回 null 给客户端。

主动删除(定期删除)

惰性删除有它的优点,不会浪费太多的系统资源,但是也存在相应的问题,就是已经过期的 Key 如果不再被访问,就不会被删除了,这样会浪费不必要的存储空间。因此 Redis 存在一种主动删除过期 Key 的策略。

主动删除也被称为定期删除,Redis 会定期扫描已经设置了过期时间的 Key,然后从中删除已经过期的 Key。Redis 默认一秒钟完成 10 次这样的扫描,它大概的流程如下:

  • 从设定了过期的 Key 中随机抽取 20 个 Key 进行过期检测
  • 删除所有已经过期的 Key
  • 如果有本次删除的 Key 超过 25%,那么重复第一步

如果有大量的 Key 过期,这样的扫描可能会导致线程卡顿,因此每次扫描的时长最长为 25ms。

以上是 Redis 处理过期 Key 的方案,当 Redis 服务器占用的内存空间超过最大允许内存之后,会触发内存的淘汰策略。

二、淘汰策略

内存淘汰策略是指 Redis 使用的内存达到或超过其配置的最大内存时触发的一种保护策略,它根据具体的策略来淘汰一些 Key 使得 Redis 可以继续运行。在 Redis 4.0 之后的版本中,Redis 的内存淘汰策略共有 8 种。

  • noeviction:内存达到配置的最大内存时,不再接受新增 Key 的操作,它是默认配置
  • allkeys-lru:在所有 Key 中,保留最近使用的 Key,删除最近最少使用的 Key
  • allkeys-lfu:在所有 Key 中,保留常用的 Key,删除最不常用的 Key
  • allkeys-random:在所有 Key 中,随机删除一些 Key
  • volatile-lru:在设置了过期时间的 Key 中,删除最近最少使用的 Key
  • volatile-lfu:在设置了过期时间的 Key 中,删除最不常用的 Key
  • volatile-random:在设置了过期时间的 Key 中,随机删除一些 Key
  • volatile-ttl:在设置了过期时间的 Key 中,删除最短剩余生存时间中最不常用的 Key

从上面的策略中可以看出,大体分为两类,分别是 allkeys 和 volatile 两种。allkeys 是所有的 Key,volatile 是设置了过期时间的 Key。在 allkeys 和 volatile 中使用两个淘汰策略是 LRU 和 LFU,即 最近最少使用(确切的是 近似 LRU 算法) 和 最不常用 两种。

三、小结

过期和淘汰是两回事,过期是对设置过期时间的 Key 进行删除的一种机制,而淘汰是当使用内存超过设置最大内存时触发的一种保护机制,虽然它也会删除一些 Key。上面整理的是关于 Redis 的过期和淘汰的知识点,具体应该怎么设置淘汰策略,官网给出了建议。需要了解 LRU 和 LFU 算法也可以在官网得到具体的说明。

Redis
大数据
缓存
分布式缓存
  • 作者:Netor0x86(联系作者)
  • 发表时间:2022-06-06 08:30
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码
  • 评论