一起学习下 Redis 过期失效策略

学习心得 做棵大树 3周前 (04-08) 147次浏览 0个评论
文章目录[隐藏]

Redis 是一个开源的使用 ANSI C 编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。

通常我们在缓存、实时排行榜等场景下会用到 Redis,这篇文章我们来一起学习下 Redis 过期失效策略。

过期失效策略

Redis 过期失效策略是 Redis 中非常重要的一个功能,它可以帮助我们管理内存使用,确保数据的时效性。以下是 Redis 中常见的几种过期失效策略:

  1. 定时过期
    定时过期是指在设置键值对的时候,同时指定一个过期时间。一旦超过这个时间,键值对就会自动被删除。这种策略可以确保数据的实时性,但是它的效率并不是很高,因为 Redis 需要为每一个设置了过期时间的键维护一个定时器。

  2. 惰性删除
    惰性删除是指当访问一个键时,如果发现这个键已经过期,那么 Redis 会立即删除这个键。这种策略可以避免不必要的定时器开销,但是如果一个键在过期后长时间没有被访问,那么这个键会一直占用内存,直到被访问或者被其他删除策略处理。对内存不太友好

  3. 定期删除
    定期删除是指 Redis 会定期扫描一定数量的键,并删除其中的过期键。这种策略是惰性删除的补充,它可以保证过期的键最终会被删除,但是它也会带来一定的性能消耗。为了不影响 Redis 的性能,通常会控制扫描的频率和数量。

  4. 内存淘汰策略
    当 Redis 的内存使用达到配置的上限时,需要进行内存淘汰。Redis 提供了多种内存淘汰策略,其中一些策略会考虑键的过期时间。例如,“volatile-lru”策略会优先淘汰设置了过期时间并且最少使用时间最长的键,“allkeys-lru”策略会淘汰所有键中最少使用时间最长的键,不考虑是否设置了过期时间。

定时过期

定时过期策略的核心思想是在键值对设置过期时间的同时,创建一个定时器,当过期时间到达时,立即删除该键值对。然而,这种策略在大规模的键值对过期时,会创建大量的定时器,对 CPU 资源造成较大压力,影响服务器的响应时间和吞吐量

在 Redis 中,并没有采用纯粹的定时过期策略,因为这种方式在处理大量过期键时效率较低。相反,Redis 采用了惰性删除和定期删除的组合策略来实现过期处理

定期删除

定期删除策略是 Redis 中实现过期键处理的另一种方式。Redis 会定期扫描一定数量的键,并删除其中的过期键。

这种策略通过限制删除操作的执行时长和频率,来减少对 CPU 时间的占用。定期删除的实现依赖于 Redis 的周期性操作,例如 serverCron 函数的执行。在每个周期性操作中,Redis 会从 expires 字典中随机抽取一定数量的键进行检查,并删除过期的键。

为了有效平衡 CPU 和内存资源的使用,Redis 的定期删除策略会根据服务器的运行情况调整执行频率。例如,如果服务器负载较高,可能会缩短定期删除的执行间隔;如果负载较低,则可能延长间隔,以减少对 CPU 资源的占用。

失效策略对比

策略 优点 缺点
定时删除 内存友好 CPU 不友好,当定时删除较多的时候,会耗费 CPU
惰性删除 CPU 友好 对内存不友好,容易造成内存堆积,可以看作是一种内存泄露
定期删除 较为中和 时间设置要合理,不然可能就是 定时删除 或者 惰性删除 了

在实际应用中,Redis 通常会结合使用这些策略,以达到最优的性能和内存管理效果。例如,

  1. 对于一些实时性要求很高的数据,可以使用定时过期策略;
  2. 对于一些不经常访问但是又需要保证时效性的数据,可以使用惰性删除和定期删除策略;
  3. 当内存使用达到上限时,可以根据业务需求选择合适的内存淘汰策略。

内存淘汰策略

Redis 提供了多种内存淘汰策略,以便在内存不足时能够自动释放空间。以下是 Redis 支持的主要内存淘汰策略,以及它们的具体描述:

  1. noeviction(无驱逐)
    当内存不足以容纳新的写入数据时,Redis 不会删除任何旧数据。对于写入操作,如果没有可用内存,Redis 会返回一个错误。这种策略下,内存的淘汰完全由用户控制,需要手动删除不需要的键。

  2. allkeys-lru(最近最少使用)
    当内存不足时,Redis 会根据数据的访问频率来删除键。最久未访问的键将被优先删除。这种策略适用于大多数使用场景,因为它可以尽量保留那些经常被访问的数据。

  3. allkeys-random(随机选择)
    与 allkeys-lru 策略类似,当内存不足时,Redis 会随机选择一些键进行删除。这种策略可能会删除一些最近被访问过的数据,但是它提供了完全随机的选择,避免了某些键因为访问模式而从未被删除的问题。

  4. volatile-lru(易失性最近最少使用)
    这种策略只考虑那些设置了过期时间的键(即易失性键)。Redis 会根据这些键的访问频率来删除最久未访问的键。对于那些不需要过期时间的键(即非易失性键),这种策略不会删除它们。

  5. volatile-random(易失性随机选择)
    与 volatile-lru 策略类似,这种策略也是只考虑易失性键。不过,它是通过随机选择的方式删除键,而不是基于访问频率。

  6. volatile-ttl(易失性时间最少)
    这种策略会删除那些 TTL(Time To Live,生存时间)最短的易失性键。也就是说,那些即将过期的键将被优先删除。对于那些有明确过期时间的键,这种策略可以帮助提前释放内存。

  7. volatile-lfu(易失性最不经常使用)
    使用 LFU(Least Frequently Used,最不经常使用),从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉

  8. allkeys-lfu(最不经常使用)

    使用 LFU(Least Frequently Used,最不经常使用),从所有的键中选择某段时间之内使用频次最少的键值对清除

LFU 策略的实现相对复杂,因为它需要跟踪每个键的使用频率,并且定期更新这些频率。在 Redis 中,可以通过设置maxmemory-policylfu来启用 LFU 内存淘汰策略。当 Redis 内存达到最大限制时,LFU 策略会根据键的使用频率来淘汰那些最不经常被访问的键。

LFU 策略适用于那些读操作模式相对固定的场景,例如,如果某些数据项经常被访问,而其他数据项很少被访问,那么 LFU 策略可以确保保留那些重要的、活跃的数据项,同时删除那些较少被使用的键,从而优化内存的使用。

需要注意的是,LFU 策略可能不适用于所有场景。例如,如果一个应用程序的数据访问模式经常变化,那么 LFU 策略可能不会提供最佳的内存使用效率。此外,LFU 策略可能会引入额外的计算开销,因为需要维护和更新每个键的使用频率。

选择合适的内存淘汰策略取决于具体的应用场景和业务需求。例如,

  1. 如果你希望保持数据的时效性,可以选择 volatile-ttl 策略;
  2. 如果你希望保持数据的热度,可以选择 allkeys-lru 策略。

在设置内存淘汰策略时,可以在 Redis 的配置文件中进行设置,或者使用CONFIG SET命令动态修改。通过合理配置内存淘汰策略,可以确保 Redis 在内存不足时仍然能够稳定运行。

参考文档

  1. Redis 简介 | Redis 中文网 (redisdocs.com)
  2. Redis 详解(十一)------ 过期删除策略和内存淘汰策 …
  3. Redis 的过期策略与内存淘汰机制:数据管理的艺术 - 百度智能云
  4. Redis 系列八--Redis 数据过期策略详解 - 阿里云开发者社区
  5. redis-定期删除策略实现 - 掘金
  6. Redis 的过期策略到底是怎么实现过期的 - 掘金
  7. Redis ttl 与 key 过期策略-CSDN 博客
  8. Redis 的过期策略是如何实现的? - 知乎
  9. 深入学习 Redis - 全局命令、过期策略如何实现、高效定时器 ...
  10. redis 的过期策略以及定时器的实现 _redis 定时器-CSDN 博客
  11. redis 的三种过期删除策略我知道,但是怎么设置? - 知乎
  12. Redis 过期时间三种删除策略详解 _redis deleteexpiry-CSDN 博客

做棵大树 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明一起学习下 Redis 过期失效策略
喜欢 (1)
[欢迎投币]
分享 (0)
关于作者:
一个整天无所事事的,有时候忽然热血的孩子
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址