Redis内存优化——内存淘汰及回收机制

news2024/11/27 2:43:16

文章目录

  • Redis内存优化——内存淘汰及回收机制
    • 内存淘汰策略
      • LRU和LFU
      • LRU和Redis的近似LRU
        • 什么是LRU
        • Redis的近似LRU
      • LFU
      • 如何选择
    • 内存回收策略
      • 惰性删除
      • 定期删除
    • 配置文件说明
    • 总结
  • 系列文章目录


本文是系列文章,为了增强您的阅读体验,已将系列文章目录放入文章末尾。👍👍👍

Redis内存优化——内存淘汰及回收机制

Redis内存淘汰及回收策略都是Redis内存优化兜底的策略,那它们是如何进行兜底的呢?先来说明一下什么是内存淘汰和内存回收策略:

  • Redis内存淘汰:当Redis的内存使用超过配置的限制时,根据一定的策略删除一些键,以释放内存空间
  • Redis内存回收:Redis通过定期删除惰性删除两种方式来清除过期的键,以保证数据的时效性和减少内存占用

内存淘汰策略

Redis内存淘汰策略是指当Redis的内存使用超过配置的最大值时,如何选择一些键进行删除,以释放空间给新的数据。Redis提供了八种内存淘汰策略,分别是:

  • noeviction:不会淘汰任何键,达到内存限制后返回错误
  • allkeys-random:在所有键中,随机删除键
  • volatile-random:在设置了过期时间的键中,随机删除键
  • allkeys-lru:通过LRU算法淘汰最近最少使用的键,保留最近使用的键
  • volatile-lru:从设置了过期时间的键中,通过LRU算法淘汰最近最少使用的键
  • allkeys-lfu:从所有键中淘汰使用频率最少的键。从所有键中驱逐使用频率最少的键
  • volatile-lfu:从设置了过期时间的键中,通过LFU算法淘汰使用频率最少的键
  • volatile-ttl:从设置了过期时间的键中,淘汰马上就要过期的键

LRU和LFU

LRU(least recently used)算法为最近最少使用算法,根据数据的历史访问记录来进行淘汰数据,优先移除最近最少使用的数据,这种算法认为最近使用的数据很大概率将会再次被使用

LFU(least frequently used)算法为最少频率使用算法,优先移除使用频率最少的数据,这种算法认为使用频率高的数据很大概率将会再次被使用

LRU和Redis的近似LRU

LRU(least recently used)算法为最近最少使用算法,根据数据的历史访问记录来进行淘汰数据,优先移除最近最少使用的数据,这种算法认为最近使用的数据很大概率将会再次被使用

什么是LRU

在算法的选择上,Redis需要能够快速地查询、添加、删除数据,也就是说查询、添加、删除的时间复杂读需为O(1)。哈希表能保证查询数据的时间复杂度为O(1)。而双向链表能保证添加、删除数据的时间复杂度为O(1),如下:
在这里插入图片描述

Redis的近似LRU

如前文所述,真实的 LRU 算法需要用链表管理所有的数据,每次访问一个数据就要移动链表节点,这样会占用额外的空间和时间。而Redis通过近似 LRU 算法,随机抽样一些键,然后比较它们的访问时间戳,这样可以节省内存和提高性能。而Redis 的近似 LRU 算法的具体实现如下:

  • 每个键值对对象(redisObject)中有一个 24 位的 lru 字段,用于记录每个数据最近一次被访问的时间戳
  • 每次按键获取一个值的时候,都会调用 lookupKey 函数,如果配置使用了 LRU 模式,该函数会更新 value 中的 lru 字段为当前秒级别的时间戳
  • 当内存达到限制时,Redis 会维护一个候选集合(pool),大小为 16
  • Redis 会随机从字典中取出 N 个键(N 可以通过 maxmemory-samples 参数设置,默认为 5),将 lru 字段值最小的键放入候选集合中,并按照 lru 大小排序
  • 如果候选集合已满,那么新加入的键必须有比集合中最大的 lru 值更小的 lru 值,才能替换掉原来的键
  • 当需要淘汰数据时,直接从候选集合中选择一个 lru 最小的键进行淘汰

举个例子,假设我们按照下面的顺序访问缓存中的数据:h,e,l,l,o,w,o,r,l,d且内存中只能存储3个字符,下面是每次访问或插入后缓存的状态,其中括号内是lru字段的值,假设初始时间戳为0

缓存状态
访问hh(0)
访问ee(1),h(0)
访问ll(2),e(1),h(0)
访问ll(3),e(1),h(0)
插入oo(4),l(3),e(1)
插入ww(5),o(4),l(3)
访问oo(6),w(5),l(3)
插入rr(7),o(6),w(5)
插入ll(8),r(7),o(6)
插入dd(9),l(8),r(7)

LFU

LFU(Least Frequently Used)是最不经常使用算法,它的思想是淘汰访问频率最低的数据。Redis在3.0版本之后引入了LFU算法,并对lru字段进行了拆分。

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

我们看lru:LRU_BITS这个字段,这个字段在LRU算法中的意义是时间戳,精确到秒。而在LFU 算法中,将它拆为两部分前16bits为时间戳,精确到分;后8为则表示该对象在一定时间段内被访问的次数。如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdeafT6f-1686030117844)(./img/redis-lfu.png)]

当Redis需要淘汰数据时,它会从内存中随机抽取一定数量(默认为5个,可以通过 maxmemory-samples 参数设置)的键值对对象,然后比较它们的访问次数和访问时间戳,找出其中最小的那个,也就是最不经常使用且最早被访问的那个,将其从内存中删除。

例如,假设我们有以下键值对和频率计数器:

频率
A13
B22
C31
D44

如果我们要添加一个新的键值对(E,5),并且缓存已经满了,那么我们就需要淘汰一个旧的键值对。我们可以随机选择A,B,C中的一个,并且发现C的频率最低,为1,所以我们就淘汰C,并且添加E到缓存中,并且将E的频率设为1。这样,缓存中的数据就变成了:

频率
A13
B22
D44
E51

如何选择

在选择上,需要根据不同的适用场景选择不同策略,如下:

策略特点适用场景
noeviction不删除任何数据,当内存不足时返回错误数据都是永久有效的,且内存足够大
allkeys-lru根据所有数据的访问时间来淘汰最久未访问的数据数据都是永久有效的,且访问时间具有明显规律
volatile-lru根据设置了过期时间的数据的访问时间来淘汰最久未访问的数据数据都有过期时间,且访问时间具有明显规律
allkeys-random随机淘汰所有类型的数据数据都是永久有效的,且访问时间没有明显规律
volatile-random随机淘汰设置了过期时间的数据数据都有过期时间,且访问时间没有明显规律
volatile-ttl根据设置了过期时间的数据的剩余生命周期来淘汰即将过期的数据数据都有过期时间,且剩余生命周期具有明显规律
allkeys-lfu根据所有数据的访问频率来淘汰最少访问的数据数据都是永久有效的,且访问频率具有明显规律
volatile-lfu根据设置了过期时间的数据的访问频率来淘汰最少访问的数据数据都有过期时间,且访问频率具有明显规律

根据8种策略的特性,也从数据完整性缓存命中率淘汰效率这三个方面详细对比了,如下:

  • 数据完整性(是否会删除永久有效的数据)
    • noevictionvolatile-lruvolatile-lfuvolatile-random 都可以保证数据完整性,因为它们不会删除永久有效的数据
    • allkeys-lruallkeys-lfuallkeys-random系列的策略则会影响数据完整性,因为它们会无差别地删除所有类型的数据
  • 缓存命中率(是否能够尽可能保留最有价值的数据)
    • allkeys-lruvolatile-lru 策略可以提高缓存命中率,因为它们会根据数据的访问时间来淘汰数据
    • allkeys-randomvolatile-random 策略则会降低缓存命中率,因为它们会随机淘汰数据
    • allkeys-lfuvolatile-lfu 策略也可以提高缓存命中率,因为它们会根据数据的访问频率来淘汰数据
    • volatile-ttl 策略则会降低缓存命中率,因为它会根据数据的剩余生命周期来淘汰数据
  • 淘汰效率(是否能够快速地找到并删除目标数据)
    • allkeys-randomvolatile-random 策略可以提高执行效率,因为它们只需要随机选择一些数据进行删除
    • allkeys-lruvolatile-lru 策略则会降低执行效率,因为它们需要对所有或部分数据进行排序
    • allkeys-lfuvolatile-lfu 策略也会降低执行效率,因为它们需要对所有或部分数据进行计数和排序
    • volatile-ttl 策略则会提高执行效率,因为它只需要对设置了过期时间的数据进行排序

内存回收策略

Redis的过期键删除有两种方式,一种是定期删除,一种是惰性删除

惰性删除

Redis惰性删除是指当一个键过期后,它并不会立即被删除,而是在客户端尝试访问这个键时,Redis会检查这个键是否过期,如果过期了,就会删除这个键。惰性删除由db.c/expireIfNeeded函数实现。

惰性删除的优点是节约CPU性能,发现必须删除的时候才删除。缺点是内存压力很大,出现长期占用内存的数据。惰性删除是Redis的默认策略,它不需要额外的配置。

惰性删除的缺点是可能会导致过期键长时间占用内存,如果访问频率较低的键过期了,但没有被访问到,那么它们就不会被惰性删除,从而浪费内存空间。

为了解决这个问题,Redis还采用了定期删除和内存淘汰机制来配合惰性删除,以达到更好的清理效果

定期删除

Redis会将设置了过期时间的键放到一个独立的字典中,称为过期字典。Redis会对这个字典进行每秒10次(由配置文件中的hz参数控制)的过期扫描,过期扫描不会遍历字典中所有的键,而是采用了一种简单的贪心策略。该策略的删除逻辑如下:

  • 从过期字典中随机选择20个键
  • 删除其中已经过期的键
  • 如果超过25%的键被删除,则重复步骤1
  • 如果本次扫描耗时超过1毫秒,则停止扫描

这种策略可以在一定程度上保证过期键能够及时被删除,同时也避免了对CPU时间的过度占用。但是它也有一些缺点,比如可能会误删一些有效的键(因为随机性),或者漏删一些无效的键(因为限制了扫描时间)

因此,Redis还结合了惰性删除策略,即在每次访问一个键之前,都会检查这个键是否过期,如果过期就删除,然后返回空值。这样可以保证不返回过期的数据,也可以节省CPU时间,但是它可能会导致一些过期的键长期占用内存,如果这些键很少被访问或者一直不被访问,那么它们就永远不会被删除

配置文件说明

Redis内存淘汰、内存回收策略相关的配置文件如下:

# 内存淘汰策略
maxmemory-policy noeviction
# 抽取数量
maxmemory-samples 5
# 最大内存
maxmemory 100mb
# 内存淘汰韧性
maxmemory-eviction-tenacity 10
# 后台任务执行间隔
hz 10
# 是否开启动态间隔
dynamic-hz yes

配置文件说明:

  • maxmemory-policy:内存淘汰策略,可选值为noeviction、allkeys-random、volatile-random、allkeys-lru、volatile-lru、allkeys-lfu、volatile-lfu、volatile-ttl其中的一个
  • maxmemory:默认值为0,也就是不限制内存的使用。
  • maxmemory-samples:抽取数量,默认为5,如果设为10将非常接近真实的LRU,但需要更多CPU资源,如果设为3将非常快,但是非常不准确。
  • maxmemory-eviction-tenacity:内存淘汰韧性,默认为10
    • maxmemory-eviction-tenacity为0时,表示不进行任何淘汰,相当于noeviction策略
    • maxmemory-eviction-tenacity为10时,表示每次淘汰键的数量为内存使用量的0.1%,每秒最多淘汰10次
  • hz:Redis后台任务执行间隔,如超时关闭客户端连接、定期删除等。默认值为10。范围在 1 到 500 之间,官方建议不要超过100,大多数应使用默认值,并且只有在极低延迟的环境中才能设为 100
  • dynamic-hz:此配置用于动态调整hz的值,默认开启。如果有大量客户端连接进来时,会以hz的配置值将作为基线,将hz的实际值设置为hz的配置值的整数倍,用来节省CPU资源。

总结

总结如下:

  • Redis内存淘汰机制是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据
  • Redis提供了八种内存淘汰策略,分别是:
    • noeviction:不会淘汰任何键,达到内存限制后返回错误
    • allkeys-random:在所有键中,随机删除键
    • volatile-random:在设置了过期时间的键中,随机删除键
    • allkeys-lru:通过LRU算法淘汰最近最少使用的键,保留最近使用的键
    • volatile-lru:从设置了过期时间的键中,通过LRU算法淘汰最近最少使用的键
    • allkeys-lfu:从所有键中淘汰使用频率最少的键。从所有键中驱逐使用频率最少的键
    • volatile-lfu:从设置了过期时间的键中,通过LFU算法淘汰使用频率最少的键
    • volatile-ttl:从设置了过期时间的键中,淘汰马上就要过期的键
  • Redis内存回收机制是指在Redis中如何删除已经过期或者被淘汰的数据,释放内存空间
  • Redis提供了两种内存回收策略,分别是:
    • 定期删除:Redis会每隔一定时间(默认100ms)随机抽取一些设置了过期时间的键,检查它们是否过期,如果过期就删除。这种策略可以减少CPU开销,但可能会导致一些过期键占用内存
    • 惰性删除:Redis在客户端访问一个键时,会检查这个键是否过期,如果过期就删除。这种策略可以及时释放内存空间,但可能会增加CPU开销和延迟

系列文章目录

Redis内存优化——String类型介绍及底层原理详解
Redis内存优化——Hash类型介绍及底层原理详解
Redis内存优化——List类型介绍及底层原理详解
Redis内存优化——Set类型介绍及底层原理详解
Redis内存优化——ZSet类型介绍及底层原理详解
Redis内存优化——Stream类型介绍及底层原理详解
Redis内存优化——Hyperloglog、GEO、Bitmap、Bitfield类型详解
Redis的三种持久化策略及选取建议
缓存更新的四种策略及选取建议

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/615828.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Yakit: 集成化单兵安全能力平台使用教程·MITM交互式劫持篇

Yakit: 集成化单兵安全能力平台使用教程MITM交互式劫持篇 1.免配置抓包2.拦截HTTPS的消息3.代理和浏览器设置4.内容规则:标记/替换流量5.过滤流量6.网站树视角1.免配置抓包 点击手工测试--MITM交互式劫持即可进入MITM劫持页面,点击免配置启动进入免配置启动设置界面(这类似…

ESP32-C2-12模组 使用乐鑫AT固件示例

ESP32C2 AT固件使用 ESP32 C2模组,如图1-1所示 图1-1 ESP32 C2模组 ESP32 C2开发板,如图1-2所示 图1-2 ESP32 C2开发 方案亮点 1、完整的 WiFi 子系统,符合 IEEE 802.11b/g/n 协议,具有 Station 模式、SoftAP 模式、SoftAP Stat…

vue3+uniapp开发小程序踩坑指南(持续更新)

小程序常见问题汇总: 1、TypeError: Cannot read property forceUpdate of undefined 原因:没有配置小程序AppID 2、define is not defined 报错一堆文件找不到,并且有define is not defined错误提示 原因:没有配置基础库或者基…

Linux安装Nginx并部署前端项目【内/外网-保姆级教程】

目录 1下载所需要的安装包 2安装步骤 2.1将下载的完整文件夹通过压缩包的形式,上传到你的路径下解压. 2.2 进入到gcc文件夹下,执行命令: 2.3进入到gcc-c文件夹下,执行命令: 2.4检查gcc、gcc-c是否安装成功 2.5执…

【深度学习】日常笔记

一开始感觉学习方向有点飘忽不定,后面查找资料和思考,发现其实图神经网络、异构图、推荐系统这三者的概念其实是相通,紧密联系的。推荐系统是指根据用户历史行为和偏好,为用户提供个性化的商品或服务推荐。而在推荐系统中&#xf…

公司新来个以前拿 20K 出来的,让我见识到了什么叫真正的测试天花板....

今天上班开早会就是新人见面仪式,听说来了个很厉害的大佬,年纪还不大,是上家公司离职过来的,薪资已经达到中高等水平,很多人都好奇不已,能拿到这个薪资应该人不简单,果然,自我介绍的…

HCIE-Cloud Computing LAB备考第二步:实战解题–第五题:论述一--双活容灾设计--记忆宫殿

文章目录 题目解法记忆宫殿存储链路要求存储业务网络链路存储复制网络链路仲裁网络链路 VRM要求主机要求存储要求 对比法存储业务网络链路和存储复制网络链路VRM和主机要求 提炼法 题目 完成FC双活设计,交由工程师搭建。为达到预期效果请把以下要求罗列出来&#x…

一文带你进入自动化测试

8年前我刚进入到IT行业,现在发现学习软件测试的人越来越多,今天我想根据自己的行业经验给大家提一些建议。 最近聊到软件测试的行业内卷,越来越多的转行和大学生进入测试行业。想要获得更好的待遇和机会,不断提升自己的技能栈成了…

001网络模型与socket的介绍

我们平常使用的程序(或者说软件)一般都是通过应用层来访问网络的,程序产生的数据会一层一层地往下传输,直到最后的网络接口层,就通过网线发送到互联网上去了。数据每往下走一层,就会被这一层的协议增加一层…

chatgpt赋能python:Python如何写配置文件-一种简单的方法

Python 如何写配置文件 - 一种简单的方法 在Python编程中,配置文件是必不可少的,因为它们允许我们在代码中保持所有可配置属性,而不是在代码中写死它们。这样,我们可以很容易地更改我们的应用程序的行为,而不必更改代…

MySQL从入门到快速上手

文章目录 第一章 了解SQL第二章 检索数据第三章 排序第四章 过滤数据第五章 高级数据过滤第六章 多表查询内连接(交集)外连接多表连接UNIONUNION ALL 第七章 单行函数日期和时间函数获取日期、时间日期与时间戳的转换获取月份、星期、星期数、天数等函数…

Banana Pi BPI-Wifi6路由器采用创耀科技TR6560/TR5220 wifi芯片方案设计,支持PoE网络供电

香蕉派BPI-Wifi6路由器设计采用了创耀科技TR6560 TR5220 wifi无线芯片设计,是一款标准的wifi6路由器解决方案。内置高性能双核ARM Cortec A9处理器,用于WIFI消息转发或智能业务处理,内置高性能LSW和硬件NAT,最大支持5Gbps的报文转…

Python 写Android App性能:入门到高级

引言 Android性能测试是移动应用开发的关键部分。无论是响应时间,内存使用,CPU占用,还是电池消耗,性能的每个方面都直接影响到用户体验。在这篇文章中,我们将介绍如何使用Python进行Android性能测试,从入门…

怎么样正确的看待档案室的八防环境监控系统

历史文化遗产是无价之宝,而如何保护它们却是一项永恒的任务。近日,盛世宏博推出了八防环境监控系统,让人惊叹不已!这个系统不仅能够实时监测温度、湿度、光照等多项指标,还能进行预警和自动调节,保障资料的…

【H5】avalon前端数据双向绑定

系列文章 C#底层库–记录日志帮助类 本文链接:https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、技术介绍二、项目源码2.1 绑定text输入框2.2 绑定select下拉框2.3 绑定radio单选按钮2.4 不使用双向绑定处理方式 三、效果展…

分布式锁工具Redisson

一、Redisson概述 二、分布式锁 三、Redisson分布式锁 四、RLock 五、公平锁 六、总结 一、Redisson概述 什么是Redisson? Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式…

笔记本安装centos操作系统

一、下载centos镜像 centos官方历史版本:Index of / 常用的镜像文件类型介绍: DVD ISO:普通光盘完整安装版镜像,可离线安装到计算机硬盘上,包含大量的常用软件(一般选择这种jing)。 Everythi…

运维小白必学篇之基础篇第十九集:rsync+inotfy实时同步

rsyncinotfy实时同步 目录 rsyncinotfy实时同步 一、服务器端 二、客户端 一、服务器端 1、安装网站服务,启动,但是不写首页文件 yum -y install httpd 2、安装raync服务 yum -y install rsync 3、修改主配置文件 (/etc/rsyncd.conf&am…

Python代码部署的三种加密方案

本文主要介绍了Python代码部署的三种加密方案,主要介绍了代码混淆、代码编译、代码打包这三种,具有一定的参考价值,感兴趣的可以了解一下 前言 最近需要源码部署一个项目,因此探索一下保护源码的方式,由简单到复杂主要…

好网角怎么发帖?文章发不出去怎么解决?

好网角怎么发帖?文章发不出去怎么解决?如何在网上发帖子?在网上发帖子#科技#电脑#网络#方法 N 如何在网上发帖子? 试用系统 windows 7 首先打开电脑中的任意浏览器,进入之后打开百度网站,点击右上角的登录…