文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

深入 Redis 系列:详解 Redis 的内存管理和缓存数据的淘汰机制

2024-11-28 15:23

关注

解决这个问题就涉及到缓存系统的一个重要机制,即缓存数据的淘汰机制。数据淘汰机制包括两步:

然而在正式介绍Redis的缓存淘汰机制之前,我们不妨关注一个问题:以系统在DB的数据量为基准,你会为你的系统缓存设置百分之多少的容量?

根据数据访问的局部性原理,在大多数的业务场景下,80% 的请求实际只访问了 20% 的数据(八二原理)。

如下图所示:

蓝线代表了“八二原理”表示的数据局部性,而红线则表示在当前应用负载下的数据局部性。蓝线描述的是正常情况下有 20% 的数据贡献了 80% 的访问量。这 80% 的数据在访问量上就形成了一条长长的尾巴,我们也称为“长尾效应”。

真实业务中,用户的个性化需求越来越多,在一个业务应用中,不同用户访问的内容可能差别很大,所以20% 的数据可能贡献不了 80% 的访问,而剩余的 80% 数据反而贡献了更多的访问量,我们称之为重尾效应。因此缓存容量占总数据量的比例,从 5% 到 40% 的都有,需要结合应用数据实际访问特征综合考虑的。一般来说,会建议把缓存容量设置为总数据量的 15% 到 30%,兼顾访问性能和内存空间开销。

说完了如何设置缓存容量以及依据之后,我们开始Redis内存管理的正题。

一、Redis内存组成、内存分配和释放

Redis的内存组成主要包括以下几个部分:

(1) 自身内存:这是Redis服务器运行所需的基本内存,包括Redis进程不存储任何key-value时本身所占用的内存。

(2) 键值对内存(key和value):

(3) 缓冲内存:

(4) 子进程内存:Redis可能会创建子进程来执行某些操作,如RDB快照持久化、AOF重写等。这些子进程也会占用相当大的内存。

(5) 内存碎片:由于Redis的内存分配器在分配和释放内存时可能会产生碎片,这些碎片会占用额外的内存空间。虽然Redis的内存分配器(如jemalloc)会尽量减少碎片的产生,但在长时间运行或频繁进行内存分配和释放的情况下,仍然可能会产生一定的内存碎片。

再说说看Redis的内存分配和释放过程。

Redis的内存分配和释放过程是其内存管理的核心环节,它确保了Redis能够高效地利用内存资源。以下是对Redis内存分配和释放过程的详细阐述:

1.内存分配过程

(1) 初始化阶段:

(2) 动态分配阶段:

(3) 内存分配策略:

2.内存释放过程

(1) 主动释放:

(2) 被动释放(内存淘汰机制):

(3) 内存碎片整理:

(4) 对象池管理:

(5) 内存回收:

二、Redis的键值过期处理策略

Redis的键值过期策略是内存管理中的重要一环。这里首先需要说一下,可能会有人将Redis的过期策略和淘汰策略给搞混,但其实两者并不是一回事。

Redis的过期策略是指对设置了过期时间的键进行管理,当这些键的过期时间到达时,Redis会采取相应的操作来删除这些键。其主要作用是确保Redis中存储的数据是有效的、最新的,并且防止无用数据长期占用内存资源。其触发条件是键的过期时间到达,这可以通过Redis的EXPIRE、PEXPIRE等命令来设置键的过期时间。

Redis的淘汰策略是指在内存使用达到上限时,为了保持Redis的稳定运行和内存的有效利用,Redis会采取一系列措施来淘汰部分键。淘汰策略的主要作用是防止Redis内存溢出,确保Redis能够持续稳定地提供服务。淘汰策略的触发条件是Redis的内存使用达到或超过其配置的最大内存限制(maxmemory)。

从作用对象来说,过期策略作用于设置了过期时间的键,而淘汰策略则可能作用于整个Redis实例中的所有键(取决于具体的淘汰策略)。

Redis的淘汰策略会在下面介绍,这里回到过期策略。

Redis对过期键的删除策略主要包括:惰性删除和定期删除。

1.惰性删除

原理:在客户端尝试访问一个键时,Redis会检查该键是否过期。如果已过期,则删除该键并返回“键不存在”的响应;否则,返回该键的值。

(1) 优点:

(2) 缺点:

2.定期删除

(1) 原理:通过一种定时任务(如Redis的serverCron)来定期删除过期键。每隔一段时间,Redis会对一部分数据库中的键进行检查,并删除其中过期的键。

(2) 优点:

(3) 缺点:

三、Redis的键值淘汰策略

首先为什么Redis需要淘汰策略呢?如果让大家回答这个问题,可能大家想到的可能只有:因为内存满了,所以需要根据一定的策略淘汰掉一些旧的或者少用的键值来存储新的或者常用的键值。但其实还可以从性能、数据一致性、内存成本和应对突发流量等角度来回答这个问题。

Redis需要淘汰策略的原因主要与其内存管理的特性和应用场景有关。以下是几个关键的原因:

那么Redis的整体淘汰键值的流程是怎么样的呢?

Redis淘汰策略的流程主要涉及内存检测、淘汰策略选择、数据取样、淘汰池维护、数据删除等步骤。以下是详细的流程说明:

1.内存检测

(1) 周期性内存检查:

(2) 判断是否需要淘汰数据:

2.淘汰策略选择

(1) 配置淘汰策略:

(2) 选择淘汰策略:

3.数据取样

(1) 随机取样:

(2) 计算访问频率或时间:

3.淘汰池维护

(1) 淘汰池初始化:

(2) 数据比较与排序:

4.数据删除

(1) 选择最佳淘汰数据:

(2) 删除数据:

(3) 更新内存使用量:

上面的Redis淘汰流程中说到,Redis会根据具体的淘汰策略来决定哪些键值应该被淘汰,下面介绍一下Redis的淘汰策略。

其实Redis的键值淘汰策略遵循主流的内存淘汰算法:LFU和LRU算法。所以在说具体的淘汰策略之前,我会先简单介绍下这两种算法的特点和实现。

5.LRU算法

(1) 原理:

LRU算法根据数据的访问时间来决定哪些数据会被淘汰。其核心思想是:最久未被访问的数据被认为是最不常用的数据,应该被优先淘汰。

(2) 实现方式:

Redis使用双向链表和哈希表来实现LRU算法。链表用于维护数据的使用顺序,链表的头部表示最新使用的数据,而链表的尾部表示最旧的数据。哈希表则用于加快数据的查找速度,哈希表的键是数据的键,值是指向双向链表节点的指针。

当有数据被访问时,Redis会将该数据从链表中当前位置移动到链表头部。这样一来,经常被访问的数据就会一直保持在链表头部,而少访问的数据就会逐渐向链表尾部移动。当需要淘汰数据时,只需要选择链表尾部的数据即可。

(3) 特点:

LRU算法实现简单,能够较好地保留热数据(即经常被访问的数据),提高命中率。

但是,LRU算法可能会受到突发性访问模式的影响,即某些数据可能只是偶尔被访问一次,但根据LRU算法,这些数据可能会被保留在内存中较长时间。

(4) 适用场景:

LRU算法适用于访问频率分布相对均匀的场景,能够较好地平衡内存使用和性能需求。

6.LFU算法

(1) 原理:

LFU算法根据数据被访问的频率来决定哪些数据会被淘汰。其核心思想是:使用频率越低的数据被认为是最不常用的数据,应该被优先淘汰。

(2) 实现方式:

Redis使用哈希表和最小堆(或其他数据结构,如双向链表和计数器等)来实现LFU算法。哈希表用于存储数据和其对应的访问频率,而最小堆则用于快速找到访问频率最低的数据。

当有数据被访问时,Redis会更新该数据在哈希表中的访问频率。当需要淘汰数据时,Redis会从最小堆中选择访问频率最低的数据进行删除。下图展示了LFU算法执行的过程。

(3) 特点:

LFU算法能够更准确地识别出那些真正不常用的数据,并将其淘汰掉。

但是,LFU算法可能会受到访问频率的波动影响,即某些数据可能在某个时间段内被频繁访问,但之后就不再被访问了。这些数据可能会因为之前的访问频率较高而被保留在内存中较长时间。

(4) 适用场景:

LFU算法适用于某些数据的访问频率明显高于其他数据的场景,能够更准确地保留热门数据并淘汰冷门数据。

三、对比与选择

对比:

了解了LRU和LFU算法是怎么一回事之后,我们再看看Redis具体的淘汰策略。Redis的主要淘汰机制及其适用场景如下:

(1) noeviction(不淘汰)

描述:当内存不足时,对写请求不再提供服务,直接返回错误(但DEL请求和部分特殊请求除外)。

适用场景:适合需要严格控制内存使用量的场景,但可能导致写入失败。当数据完整性或写入操作的重要性高于缓存性能时,可以选择此策略。

(2) allkeys-lru(从所有key中使用LRU算法淘汰)

描述:使用LRU(Least Recently Used,最近最少使用)算法从所有key中选择最久未使用的数据进行淘汰。

适用场景:适用于缓存场景,确保常用数据优先保留,不区分是否设置过期时间。当数据访问模式具有明显的时间局部性(即最近被访问的数据更有可能在未来被访问)时,此策略效果较好。

(3) volatile-lru(从设置了过期时间的key中使用LRU算法淘汰)

描述:仅对设置了过期时间的key使用LRU算法进行淘汰。

适用场景:适合需要定期清理过期数据的场景,同时希望保留最近使用的数据。当数据具有明确的过期时间,并且希望确保在内存紧张时优先淘汰这些过期数据中较久未使用的部分时,此策略较为合适。

(4) allkeys-random(从所有key中随机淘汰)

描述:从所有key中随机选择数据进行淘汰。

适用场景:适用于缓存策略不明确的场景,或者当数据访问模式没有明显的规律时。此策略较为随机,不保证常用数据优先保留。

(5) volatile-random(从设置了过期时间的key中随机淘汰)

描述:仅对设置了过期时间的key进行随机淘汰。

适用场景:适合不确定热点数据的场景,但随机淘汰方式可能不适合对性能有要求的应用。当数据具有过期时间,且对淘汰哪部分数据没有特定要求时,可以选择此策略。

(6) volatile-ttl(淘汰过期时间剩余最短的)

描述:在设置了过期时间的key中,淘汰过期时间剩余最短的。

适用场景:适合短时间内需要清除快过期的数据,但不适合热点数据访问的场景。当希望优先淘汰那些即将过期的数据时,此策略较为合适。

(7) allkeys-lfu(从所有key中使用LFU算法淘汰,如果Redis版本支持)

描述:使用LFU(Least Frequently Used,最少频率使用)算法从所有key中选择访问频率最低的数据进行淘汰。

适用场景:适用于访问模式稳定但不同key的访问频率差异明显的场景。当希望保留那些经常被访问的数据,并淘汰那些很少被访问的数据时,此策略效果较好。

(8) volatile-lfu(从设置了过期时间的key中使用LFU算法淘汰,如果Redis版本支持)

描述:仅对设置了过期时间的key使用LFU算法进行淘汰。

适用场景:适合需要在一定时间内淘汰使用频率较低的数据的场景,同时这些数据具有明确的过期时间。当希望确保在内存紧张时优先淘汰那些过期数据中访问频率较低的部分时,此策略较为合适。

来源:程序员阿沛内容投诉

免责声明:

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

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

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯