Redis 过期策略与内存淘汰策略总结

个人学习 Redis 的总结学习笔记,参考资料都在文末给出,建议阅读
内容较多,点赞收藏不迷路~


文章目录

    • 键的过期时间
        • 判定
        • 删除策略
          • 定时删除
          • 惰性删除
          • 定期删除
            • 优点
            • 难点
    • 数据淘汰策略
        • 拓展阅读

键的过期时间

Redis 可以为每个键设置过期时间,当键过期时,会自动删除该键。

对于散列表这种容器,只能为整个键设置过期时间(整个散列表),而不能为键里面的单个元素设置过期时间。

判定

存在一个过期字典,存放着对应键的过期时间(什么时候)或者生存时间(生存多久)。

  1. 检查给定键是否存在于过期字典:如果存在,那么取得键的过期时间。
  2. 检查当前时间戳是否大于键的过期时间。

在主从模式中,如果一个键在主服务器中被标记为过期,而从服务器中该键并未被标记过期。此时客户端可以通过从服务器获得该键,但是对该键的处理会提交给主服务器,主服务器发现该键已过期,将会告知客户端,并让从服务器把该键也标记为过期。

删除策略

redis 中使用的是惰性删除 + 定期删除。

定时删除

设置键的过期时间同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。

  • 内存友好

    保证过期键会尽可能快地被删除,并释放所占用的内存

  • CPU时间不友好

    如果过期键较多,删除键时所占用时间就会增多,影响服务器的响应时间和吞吐量。

惰性删除

所有读写数据库的 Redis 命令在执行之前都会调用一个函数对输入键进行检查。每次从键空间中获取键时,检查取得的键是否过期,如果已过期,就删除该键,未过期则返回该键。

  • CPU友好

    程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会必要时进行,仅在当前的键花费CPU时间。

  • 内存不友好

    过期的键会被保存在内存中得不到处理,直至被调用之前会一直占用内存空间,浪费太多内存,容易造成内存泄漏。

定期删除

是定时删除和惰性删除的整合和折中。

在规定时间内,分多次遍历服务器中的各个数据库,将每一次遍历结束的数据库记录下来作为下一次遍历的起点,从过期字典中随机检查一部分键的过期时间,并删除其中的过期键。

优点
  • 通过限制删除操作执行的时间和频率来减少删除操作对CPU时间的影响。

  • 减少了因为过期键过多带来的内存浪费。

难点
  • 操作时间过于频繁或过长,会退化成定时删除策略。
  • 操作次数太少或时间过短,会退化成惰性策略。

Redis 过期策略与内存淘汰策略总结_第1张图片

数据淘汰策略

Redis在使用内存达到某个阈值(通过maxmemory配置)的时候,就会触发内存淘汰机制,选取一些key来删除。

Redis 具体有 6 种淘汰策略:

策略 描述
volatile-lru 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
volatile-ttl 从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random 从已设置过期时间的数据集中任意选择数据淘汰
allkeys-lru 从所有数据集中挑选最近最少使用的数据淘汰
allkeys-random 从所有数据集中任意选择数据进行淘汰
noeviction 禁止驱逐数据

作为内存数据库,出于对性能和内存消耗的考虑,Redis 的淘汰算法实际实现上并非针对所有 key,而是抽样一小部分并且从中选出被淘汰的 key。

使用 Redis 缓存数据时,为了提高缓存命中率,需要保证缓存数据都是热点数据。可以将内存最大使用量设置为热点数据占用的内存量,然后启用 allkeys-lru 淘汰策略,将最近最少使用的数据淘汰。

Redis 4.0 引入了 volatile-lfu 和 allkeys-lfu 淘汰策略,LFU 策略通过统计访问频率,将访问频率最少的键值对淘汰。

如何选取合适的策略?

比较推荐的是两种lru策略。根据自己的业务需求。如果你使用Redis只是作为缓存,不作为DB持久化,那推荐选择allkeys-lru;如果你使用Redis同时用于缓存和数据持久化,那推荐选择volatile-lru。

拓展阅读

《Redis 五大数据类型》

《Redis 跳表与实现》

《说说 Redis 中的字典?》


如果对你有帮助,请点个赞,加个收藏噢!

参考资料

《Redis设计与实践》
cyc2018

你可能感兴趣的:(Redis)