【虹科干货】Redis 开发者需要了解的缓存驱逐策略

在你 搭建并配置了一个Redis数据库 之后 Redis成功地 提升了应用程序性能 。然而 这里有一个潜在问题, 随着缓存数据的快速增加和内存占用率的逐渐上升, 很快会发现Redis缓存 容量即将达到硬件存储容量上限 。或许 你曾 听说 过缓存驱逐 来解决这个问题 ,但 究竟是怎么一回事呢?

无论 是在新兴企业中担任开发人员,还是在大型企业中担任系统管理员,了解缓存驱逐策略,并了解何时以及如何 使用 ,都至关重要。 在本文中 ,我们将深入探讨这些细节,让 对缓存驱逐有更清晰的认识。


一、对 缓存驱逐的理解

Redis或任何依赖缓存的系统 中, 缓存驱逐策略都至关重要。它是解决缓存空间大小和内存占用问题的关键。当缓存 数据 达到 硬件容量上限 时,缓存系统必须做出决策:是拒绝接收新的数据,还是通过丢弃旧的数据为新数据腾出空间?

此时,缓存驱逐就发挥作用了。 为了保持性能和数据一致性,在 缓存达到上限 时,缓存系统需要进行一系列判断,以确定应该保留哪些缓存 数据 ,或者需要丢弃哪些缓存 数据

缓存驱逐是指从缓存中删除特定数据的过程。 当缓存达到 硬件 最大存储容量时,必须删除一些数据,为新数据腾出空间。

二、 缓存驱逐策略

缓存驱逐策略是 一种协议,它解决的问题是当 缓存 达到上限 时,缓存系统需要如何应对。不同的策略对应不同的程序 实现,用于确定应该驱逐(即删除)哪些旧数据。以下是一些常见的策略。

·  最近最少使用(Least Recently Used ,  LRU) :想象一下,您正在整理衣柜,您会优先扔掉哪些物品? 是学生时代遗留的格子衬衫,还是近期购入的一顶鸭舌帽? LRU缓存驱逐策略会首先 删除近期 被访问 次数 最少的缓存 数据 。其基本假设是不经常被访问的 数据 在短期内不会再次被访问。

·  最不频繁使用(Least Frequently Used, LFU) :假设 是一名图书管理员, 将如何选择要从图书馆书架上移除的书籍?很可能是那些被借阅次数最少的书籍 这也是LFU缓存驱逐策略的思想。 LFU策略会优先驱逐最不经常被访问的缓存 数据, 其基本假设是 近期不再需要这些 项目。

·  Window TinyLFU(W-TinyLFU) :这个策略稍微复杂一些。想象一下, 是一名电台DJ, 希望播放那些受欢迎且最近热门的歌曲。 W-TinyLFU缓存驱逐策略根据数据的新旧程度和访问频率 判断数据的价值,从而将最有价值的数据 保留在缓存中。W-TinyLFU在处理多变的访问模式和分布式缓存环境时尤为有效。

·  生存时间(Time to Live, TTL) :想象一下, 冰箱里 有一盒新鲜的 圣女果 ,如果在冰箱里放太久,就会开始变质。此时,不管 有多喜欢它们,都应该将它们扔掉。 TTL在缓存中有类似的概念。每个缓存 数据 都有一个特定的 “过期时间”。一旦达到该时间限制,无论访问频率或最近访问次数如何, 数据 都会被驱逐。这种策略可以确保 过时的数据被及时清除 。它适用于需要定期更新数据,并确保缓存不提供旧 数据 的情况。

策略的有效性取决于具体的使用情况,没有一种策略适用于所有场景。在选择和 使用 缓存驱逐策略时,需要仔细考虑应用程序的特定需求和数据访问模式。

三、采用默认设置的风险

Redis中,默认的驱逐策略是易失性LRU(volatile-LRU)。但仅仅依赖默认策略而不了解其潜在影响 ,就 可能存在一定风险。应用程序服务于多样化的用户需求,数据模式和 数据 驱逐要求可能存在巨大差异。 通过正确设置驱逐策略可以预防潜在的问题。

1、第一道防线:监控

首先,我们需要监控缓存性能以确认何时需要进行驱逐操作。我们通过监控工具达成这一目的。

Redis中,可以通过 INFO命令 来监控缓存性能, 也可以 使用 第三方监控工具 提供更详细的性能分析。

优化缓存性能涉及两个方面,需要根据监控性能时所发现的信息,对缓存设置和缓存驱逐策略进行调整。分布式缓存场景中,监控与调优在确保跨多节点一致、缓存 高效管理时尤为重要。

2、选择合适的Redis驱逐策略

Redis中,缓存由maxmemory配置指令进行管理,该指令用于设置内存限制。而maxmemory-policy配置指令则根据所选择的缓存驱逐策略来指导Redis进行驱逐决策。这些配置项都存储在redis.conf配置文件中。

Redis提供了多种驱逐策略,但以下几种可能是 最关心的策略。

(1)  allkeys-lru

Redis的allkeys-lru策略用于删除最近最少使用的缓存 数据 ,且无论是否设置了过期时间。

·  这个策略中,Redis会额外记录每个键的最后访问时间。每次读取或写入键时,Redis会更新这个信息。

·  Redis达到内存限制并且需要驱逐 数据 时,它会寻找最长时间未被访问的键,也就是"最近最少使用"的键。

·  接着,Redis会删除这些键,为新的数据腾出可用的空间。

allkeys-lru策略适用于Redis数据库中的所有键,无论是否设置了过期时间。与volatile-lru策略不同的是,后者仅适用于设置了过期时间的键。

(2)  volatile-lru

volatile-lru策略用于删除设置了过期时间的最近最少使用的缓存 数据 。这个策略适用于那些需要定期刷新数据的场景。

(3)  allkeys-lfu

allkeys-lfu策略会删除使用频率最低的键。

·  在这个策略中,Redis会记录每个键的访问频率。每次读取或写入键时,Redis会更新与键相关联的计数器。

·  Redis达到内存限制时,它会寻找具有最低 访问频率 的键

·  然后,Redis会删除这些键,为新的数据腾出可用的空间。

(4)  volatile-lfu

allkeys-lfu类似,volatile-lfu策略仅适用于设置了过期时间的键。 且按访问频率评判键的价值,当缓存达到上限时,删除访问频率最低的键。

(5)  volatile-ttl

volatile-ttl策略优先删除具有最短TTL的键。

·  这个策略中,Redis会记录每个键的TTL,即键的生存时间。TTL是一个持续时间,在到期之后,键将自动删除。

·  Redis达到内存限制时,它会寻找具有最短TTL的键,也就是即将过期的键。

·  Redis会删除这些键,为新的数据腾出可用的空间。

(6)  noeviction

顾名思义, noeviction策略是当Redis达到内存限制并收到写入命令时,不会驱逐任何键,而是返回错误。

·  Redis达到内存限制并且收到写入命令时,它会检查驱逐策略。

·  如果策略设置为noeviction,则Redis不会驱逐任何键,而是向写入命令返回错误。

·  在这种情况下,应用程序代码需要确定如何处理该错误条件。

 

事实上,以上 每种策略都 有其优缺点,最适合的策略 需要依 具体业务需求 而定

当处理大量数据时,使用良好结构的缓存,并结合适当的缓存驱逐策略,可以更好地 保持 缓存的性能。Redis以其丰富的功能成为优秀的缓存解决方案,并为处理大型数据集的应用程序提供了强大的支持。有效的缓存管理不仅能通过缓存命中加快数据检索,还能减轻缓存未命中的影响,使得Redis成为各种用例中可靠且高效的缓存解决方案。

 


请使用浏览器的分享功能分享到微信等