Skip to main content

03小节:如何设置Redis内存淘汰策略?

作者:程序员马丁

在线博客:https://nageoffer.com

note

热门项目实战社群,收获国内众多知名公司面试青睐,近千名同学面试成功!助力你在校招或社招上拿个offer。

如何设置Redis内存淘汰策略,元数据信息:

©版权所有 - 拿个offer-开源&项目实战星球专属学习项目,依据《中华人民共和国著作权法实施条例》《知识星球产权保护》,严禁未经本项目原作者明确书面授权擅自分享至 GitHub、Gitee 等任何开放平台。违者将面临法律追究。


内容摘要:通过分析缓存击穿场景,引出了 Redis 内存淘汰策略。详细介绍了 Redis 中的各种淘汰策略,并指出实际工作中常用的策略。在牛券项目中,说明了选择的淘汰策略以及选择的原因。最后,还讨论了一些关于内存淘汰的底层原理。

课程目录如下所示:

  • 业务背景
  • 什么是 Redis 内存淘汰?
  • 什么是缓存污染问题?
  • 淘汰策略对缓存击穿的影响?
  • 牛券选择哪个淘汰策略?
  • 内存淘汰底层原理

业务背景

在之前讨论缓存击穿的问题时,有一个关键点没有详细介绍,那就是如何与 Redis 的内存淘汰策略结合使用。仅仅依靠缓存预热和设置数据永不过期并不是一个全面的解决方案,还需要考虑合适的内存淘汰策略来保障缓存击穿方案有效执行。

什么是内存淘汰?

内存总是有限的,因此当 Redis 内存超出最大内存时,就需要根据一定的策略去主动的淘汰一些 Key,来腾出内存,这就是内存淘汰策略。我们可以在配置文件中通过 maxmemory-policy 配置指定策略。

与到期删除策略不同,内存淘汰策略主要目的则是为了防止运行时内存超过最大内存,所以尽管最终目的都是清理内存中的一些 Key,但是它们的应用场景和触发时机是不同的。

算上在 4.0 添加的两种基于 LFU 算法的策略, Redis 一共提供了八种策略供我们选择:

  • noeviction,不淘汰任何 key,直接报错。它是默认策略。
  • volatile-random:从所有设置了到期时间的 Key 中,随机淘汰一个 Key。
  • volatile-lru: 从所有设置了到期时间的 Key 中,淘汰最近最少使用的 Key。
  • volatile-lfu: 从所有设置了到期时间的 Key 中,淘汰最近最不常用使用的 Key(4.0 新增)。
  • volatile-ttl: 从所有设置了到期时间的 Key 中,优先淘汰最早过期的 Key。
  • allkeys-random:从所有 Key 中,随机淘汰一个键(4.0 新增)。
  • allkeys-lru: 从所有 Key 中,淘汰最近最少使用的 Key。
  • allkeys-lfu: 从所有 Key 中,淘汰最近最不常用使用的键。

从淘汰范围来说可以分为不淘汰任何数据、只从设置了到期时间的键中淘汰和从所有键中淘汰三类。而从淘汰算法来分,又主要分为 Random(随机),LRU(最近最少使用),以及 LFU(最近最不常使用)三种。

其中,关于 LRU 算法,它是一种非常常见的缓存淘汰算法。我们可以简单理解为 Redis 会在每次访问 Key 的时候记录访问时间,当淘汰时,优先淘汰最后一次访问距离现在最早的 Key。

而对于 LFU 算法,我们可以理解为 Redis 会在访问 Key 时,根据两次访问时间的间隔计算并累加访问频率指标,当淘汰时,优先淘汰访问频率指标最低的 key。相比 LRU 算法,它避免了低频率的大批量查询造成的缓存污染问题。

什么是缓存污染问题?

LRU 有个最大问题,就是它只认最近一次访问时间。而如果出现系统偶尔需要一次性读取大量数据的时候,会大规模更新 Key 的最近访问时间,从而导致真正需要被频繁访问的 Key 因为最近一次访问时间更早而被直接淘汰。这种情况被称为缓存污染。为此,我们需要使用 LFU 算法来解决。

淘汰策略对缓存击穿的影响?

举个例子,我们操作了缓存预热和设置 Redis 永不过期,如果说设置 Redis 内存淘汰策略是以下类型:

  • allkeys-random:从所有 Key 中,随机淘汰一个键(4.0 新增)。
  • allkeys-lru: 从所有 Key 中,淘汰最近最少使用的 Key。
  • allkeys-lfu: 从所有 Key 中,淘汰最近最不常用使用的键。

因为是从所有键中去执行淘汰算法,是否有可能将咱们设置的热 Key 或者说访问较多的 Key 给淘汰掉?第一种绝对有可能,第二三种虽然概率比较小,但是也不是没可能。

所以,我们只能从这几个淘汰算法中进行选择:

  • noeviction,不淘汰任何 Key,直接报错。
  • volatile-random:从所有设置了到期时间的 Key 中,随机淘汰一个 Key。
  • volatile-lru: 从所有设置了到期时间的 Key 中,淘汰最近最少使用的 Key。
  • volatile-lfu: 从所有设置了到期时间的 Key 中,淘汰最近最不常用使用的 Key(4.0 新增)。
  • volatile-ttl: 从所有设置了到期时间的 Key 中,优先淘汰最早过期的 Key。

牛券选择哪个淘汰策略?

从常规上来说,如果大家公司 Redis 比较豪,也就是业务挣钱,在资源上不吝啬,必然毫不犹豫选择 noeviction 不淘汰任何任何数据。

解锁付费内容,👉 戳