我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis中LRU淘汰策略的深入分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis中LRU淘汰策略的深入分析

前言

Redis作为缓存使用时,一些场景下要考虑内存的空间消耗问题。Redis会删除过期键以释放空间,过期键的删除策略有两种:

  • 惰性删除:每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
  • 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。

另外,Redis也可以开启LRU功能来自动淘汰一些键值对。

LRU算法

当需要从缓存中淘汰数据时,我们希望能淘汰那些将来不可能再被使用的数据,保留那些将来还会频繁访问的数据,但最大的问题是缓存并不能预言未来。一个解决方法就是通过LRU进行预测:最近被频繁访问的数据将来被访问的可能性也越大。缓存中的数据一般会有这样的访问分布:一部分数据拥有绝大部分的访问量。当访问模式很少改变时,可以记录每个数据的最后一次访问时间,拥有最少空闲时间的数据可以被认为将来最有可能被访问到。

举例如下的访问模式,A每5s访问一次,B每2s访问一次,C与D每10s访问一次,|代表计算空闲时间的截止点:

~~~~~A~~~~~A~~~~~A~~~~A~~~~~A~~~~~A~~|
~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~|
~~~~~~~~~~C~~~~~~~~~C~~~~~~~~~C~~~~~~|
~~~~~D~~~~~~~~~~D~~~~~~~~~D~~~~~~~~~D|

可以看到,LRU对于A、B、C工作的很好,完美预测了将来被访问到的概率B>A>C,但对于D却预测了最少的空闲时间。

但是,总体来说,LRU算法已经是一个性能足够好的算法了

LRU配置参数

Redis配置中和LRU有关的有三个:

  • maxmemory: 配置Redis存储数据时指定限制的内存大小,比如100m。当缓存消耗的内存超过这个数值时, 将触发数据淘汰。该数据配置为0时,表示缓存的数据量没有限制, 即LRU功能不生效。64位的系统默认值为0,32位的系统默认内存限制为3GB
  • maxmemory_policy: 触发数据淘汰后的淘汰策略
  • maxmemory_samples: 随机采样的精度,也就是随即取出key的数目。该数值配置越大, 越接近于真实的LRU算法,但是数值越大,相应消耗也变高,对性能有一定影响,样本值默认为5。

淘汰策略

淘汰策略即maxmemory_policy的赋值有以下几种:

  • noeviction:如果缓存数据超过了maxmemory限定值,并且客户端正在执行的命令(大部分的写入指令,但DEL和几个指令例外)会导致内存分配,则向客户端返回错误响应
  • allkeys-lru: 对所有的键都采取LRU淘汰
  • volatile-lru: 仅对设置了过期时间的键采取LRU淘汰
  • allkeys-random: 随机回收所有的键
  • volatile-random: 随机回收设置过期时间的键
  • volatile-ttl: 仅淘汰设置了过期时间的键---淘汰生存时间TTL(Time To Live)更小的键

volatile-lru, volatile-random和volatile-ttl这三个淘汰策略使用的不是全量数据,有可能无法淘汰出足够的内存空间。在没有过期键或者没有设置超时属性的键的情况下,这三种策略和noeviction差不多。

一般的经验规则:

  • 使用allkeys-lru策略:当预期请求符合一个幂次分布(二八法则等),比如一部分的子集元素比其它其它元素被访问的更多时,可以选择这个策略。
  • 使用allkeys-random:循环连续的访问所有的键时,或者预期请求分布平均(所有元素被访问的概率都差不多)
  • 使用volatile-ttl:要采取这个策略,缓存对象的TTL值最好有差异

volatile-lru 和 volatile-random策略,当你想要使用单一的Redis实例来同时实现缓存淘汰和持久化一些经常使用的键集合时很有用。未设置过期时间的键进行持久化保存,设置了过期时间的键参与缓存淘汰。不过一般运行两个实例是解决这个问题的更好方法。

为键设置过期时间也是需要消耗内存的,所以使用allkeys-lru这种策略更加节省空间,因为这种策略下可以不为键设置过期时间。

近似LRU算法

我们知道,LRU算法需要一个双向链表来记录数据的最近被访问顺序,但是出于节省内存的考虑,Redis的LRU算法并非完整的实现。Redis并不会选择最久未被访问的键进行回收,相反它会尝试运行一个近似LRU的算法,通过对少量键进行取样,然后回收其中的最久未被访问的键。通过调整每次回收时的采样数量maxmemory-samples,可以实现调整算法的精度。

根据Redis作者的说法,每个Redis Object可以挤出24 bits的空间,但24 bits是不够存储两个指针的,而存储一个低位时间戳是足够的,Redis Object以秒为单位存储了对象新建或者更新时的unix time,也就是LRU clock,24 bits数据要溢出的话需要194天,而缓存的数据更新非常频繁,已经足够了。

Redis的键空间是放在一个哈希表中的,要从所有的键中选出一个最久未被访问的键,需要另外一个数据结构存储这些源信息,这显然不划算。最初,Redis只是随机的选3个key,然后从中淘汰,后来算法改进到了N个key的策略,默认是5个。

Redis3.0之后又改善了算法的性能,会提供一个待淘汰候选key的pool,里面默认有16个key,按照空闲时间排好序。更新时从Redis键空间随机选择N个key,分别计算它们的空闲时间idle,key只会在pool不满或者空闲时间大于pool里最小的时,才会进入pool,然后从pool中选择空闲时间最大的key淘汰掉。

真实LRU算法与近似LRU的算法可以通过下面的图像对比:

浅灰色带是已经被淘汰的对象,灰色带是没有被淘汰的对象,绿色带是新添加的对象。可以看出,maxmemory-samples值为5时Redis 3.0效果比Redis 2.8要好。使用10个采样大小的Redis 3.0的近似LRU算法已经非常接近理论的性能了。

数据访问模式非常接近幂次分布时,也就是大部分的访问集中于部分键时,LRU近似算法会处理得很好。

在模拟实验的过程中,我们发现如果使用幂次分布的访问模式,真实LRU算法和近似LRU算法几乎没有差别。

LRU源码分析

Redis中的键与值都是redisObject对象:


typedef struct redisObject {
 unsigned type:4;
 unsigned encoding:4;
 unsigned lru:LRU_BITS; 
 int refcount;
 void *ptr;
} robj;

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis中LRU淘汰策略的深入分析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis中LRU淘汰策略是怎么工作的

在Redis中,LRU(Least Recently Used,最近最少使用)淘汰策略是一种缓存淘汰算法,它根据键的最近使用时间来决定哪些键应该被淘汰。具体工作原理如下:当一个新键被插入到缓存中时,该键的访问时间会被更新为当前时间。当缓存
Redis中LRU淘汰策略是怎么工作的
2024-05-07

深入理解redis删除策略和淘汰策略

目录1、Redis的删除策略2、三种删除策略 (1)、定时删除(2)、惰性删除 (3)、定期删除 3、三种策略对比 4、淘汰/逐出策略 (1)、淘汰策略分类1、redis的删除策略Redis 是一种内存级数据库,数据都存在内存中,但是针对
深入理解redis删除策略和淘汰策略
2024-08-31

深入理解Redis内存淘汰策略

目录一、内存回收二、设置内存三、内存淘OMrIioOBX汰策略四、LRU4.1 LRU算法4.2 redis中的LRU算法五、LFU一、内存回收长时间不使用的缓存降低IO性能物理内存不够很多人了解了Redis的好处之后,于是把任何数据
2022-07-05

Redis过期键与内存淘汰策略深入分析讲解

目录一、Redis数据库的组织方式1.1 redisServer结构定义1.2 redisDb 结构定义1.3 redisdb初始化二、过期键2.1 设置键的过期时间2.2 过期键的判定2.3 过期键的删除策略2.3.1 惰性删除的实现2.
2022-11-28

Redis的过期策略和内存淘汰策略最全总结与分析

文章前言提到内存管理,我们就需要考虑Redis的内存过期策略和内存淘汰机制。该文章便从这两方面入手,分享一些在Redis内存方面相关的基础知识。文章中使用的示例版本为Redis5.0版本。内存过期策略内存过期策略主要的作用就是,在缓存过期之后,能够及时的将失效
Redis的过期策略和内存淘汰策略最全总结与分析
2016-07-21

Redis中AOF与RDB持久化策略深入分析

目录写在前面一、Redis为什么要持久化二、Redis的持久化方式2.1. AOF持久化(Append of file)2.1.1 fsync 系统调用2.1.2 AOF持久化策略2.1.3 aof_rewrite2.2 RDB快照(red
2022-11-28

Redis中的过期删除策略和内存淘汰机制是什么

这篇文章主要讲解了“Redis中的过期删除策略和内存淘汰机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis中的过期删除策略和内存淘汰机制是什么”吧!Redis 中 key 的
2023-06-29

Redis中过期策略的示例分析

小编给大家分享一下Redis中过期策略的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!概述设置过期时间expire key time(以秒为单位) 这是最
2023-06-15

如何深入分析Kafka架构的工作流程、存储机制、分区策略

这期内容当中小编将会给大家带来有关如何深入分析Kafka架构的工作流程、存储机制、分区策略,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、前言在开始之前首先要明确一点,kafka是一个分布式流平台,本质
2023-06-02

JVM内存管理深入垃圾收集器与内存分配策略的示例分析

这篇文章给大家介绍JVM内存管理深入垃圾收集器与内存分配策略的示例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出
2023-06-17

数据库水平分割与垂直分割的区别:深入解析两种分区分区策略

数据库的水平分割和垂直分割是两种常见的分区策略,它们在数据存储和管理方面具有不同的特点和应用场景。本文将深入解析这两种分区策略,帮助读者了解它们的异同和优缺点,以便根据实际需求选择合适的数据库分区策略。
数据库水平分割与垂直分割的区别:深入解析两种分区分区策略
2024-02-23

数据库死锁:深入剖析数据库中的“死循环”及其应对策略

数据库死锁是指两个或两个以上的事务由于循环等待对方的资源而导致无法继续执行的情况。为了解决死锁问题,数据库使用死锁检测和死锁预防机制,努力打破死锁循环。
数据库死锁:深入剖析数据库中的“死循环”及其应对策略
2024-02-05

编程热搜

目录