当前位置: 首页 > news >正文

Redis过期删除策略

目录

    • 引出
    • Redis过期删除策略
      • Redis的两种过期策略:定期删除 + 惰性删除
      • 定期删除
      • 惰性删除
      • Redis两种过期删除策略存在的问题
    • Redis缓存淘汰策略
    • Redis中的LRU和LFU算法
      • 1、LRU(Least Recently Userd最近最少使用)
      • LFU 算法的引入
      • 2、LFU(least Frequently Userd最近最不频繁使用)

引出

Redis的key达到过期时间,Redis就会马上删除么?
结论是:并不会立马删除
为什么并不会立马删除,这个时候我们就需要说到Redis的数据过期清除策略 与 内存淘汰策略

  在使用Redis时,我们一般会为Redis的缓存空间设置一个大小,不会让数据无限制地放入Redis缓存中。可以使用下面命令来设定缓存的大小,比如设置为4GB:
 

CONFIG SET maxmemory 4gb
 

既然 Redis 设置了缓存的容量大小,那缓存被写满就是不可避免的。当缓存被写满时,我们需要考虑下面两个问题:决定淘汰哪些数据,如何处理那些被淘汰的数据。
 
 

Redis过期删除策略

  如果我们设置了Redis的key-value的过期时间,当缓存中的数据过期之后,Redis就需要将这些数据进行清除,释放占用的内存空间。Redis中主要使用 定期删除 + 惰性删除 两种数据过期清除策略。

Redis的两种过期策略:定期删除 + 惰性删除

定期删除

Redis的定期删除是指:Redis默认每隔0.1s随机抽取一些设置了过期时间的key,检查这些key是否过期,如果有过期就删除。

  注意这里是随机抽取,那为什么要随机抽取呢?我们可以想一想看,如果redis中存了十几万个key,每隔0.1s就遍历所有设置过期时间的key的话,会给CPU带来很大的负担的。

问题:Redis中为什么不直接使用定期删除策略呢?
定时删除,会用一个定时器来负责监视key,过期则将这些key删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求上,而不是删除key上,所以就没有采用这一策略。

惰性删除

定期删除可能导致很多过期的可以到了过期时间并没有被删除掉,这个时候就要使用到惰性删除。
Redis的惰性删除是指:在你获取某个key时,redis会检查一下,这个key是否设置了过期时间并且是否已经过期,是的话就删除。

Redis两种过期删除策略存在的问题

  如果某个key过期后,定期删除没有删除成功,然后也没有去请求key,也就是说惰性删除也没有生效。这个时候,如果大量过期的key堆积在内存中,redis的内存会越来越高,导致redis的内存耗尽。这个时候我们就应该采用Redis的缓存淘汰机制了。

 
 

Redis缓存淘汰策略

Redis一共提供了八种缓存淘汰策略。如下图

 
在这里插入图片描述
 

1、noeviction:不进行淘汰数据。一旦缓存被写满,再有写请求进来,Redis就不再提供服务,而是直接返回错误。
2、volatile-ttl:在设置了过期时间的键值对中,移除即将过期的键值对。
3、volatile-random:在设置了过期时间的键值对中,随机移除某个键值对。
4、volatile-lru:在设置了过期时间的键值对中,移除最近最少使用的键值对。
5、volatile-lfu:在设置了过期时间的键值对中,移除最近最不频繁使用的键值对。
6、allkeys-random:在所有键值对中,随机移除某个key。
7、allkeys-lru:在所有的键值对中,移除最近最少使用的键值对。
8、allkeys-lfu:在所有的键值对中,移除最近最不频繁使用的键值对。

这么多Redis缓存淘汰策略,我们该如何选择呢?

通常情况下,推荐优先选择 allkeys-lru 策略。这样可以充分利用LRU这一经典的缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。

如果我们的业务数据中有明显的冷热数据区分,那么建议我们使用 allkeys-lru 策略。

如果我们的业务数据访问频率相差不大,没有明显的冷热数据的区分,那么建议我们使用 allkeys-random 策略,随机选择淘汰的数据就行。

对于那些没有设置过期时间的键值对,那么使用如 volatile-lru , volatile-lfu , volatile-random 和 volatile-ttl 策略的行为和noeviction 基本上是一致的,一旦缓存被写满,再有写请求进来,Redis就不再提供服务,而是直接返回错误。

我们来说说最主要的两个算法:LRU(Least Recently Userd最近最少使用)和LFU(least Frequently Userd最近最不频繁使用)算法

首先我们先说一下他们两个的区别:

LRU(Least Recently Userd):最近最少使用,跟使用的最后一次时间有关,淘汰离现在最久的。
LFU(least Frequently Userd):最近最不频繁使用,跟使用的次数有关,淘汰使用次数最少的。

 
 

Redis中的LRU和LFU算法

 

1、LRU(Least Recently Userd最近最少使用)

LRU算法的全称是 Least Recently Uses,按照最近最少使用的原则来筛选数据,最不常用的数据会被筛选出来。LRU算法会把所有的数据组织成为一个链表,链表的头和尾表示MRU端和LRU端,分别表示最近最常使用最近最不常使用的数据,我们来看一个例子。

 
在这里插入图片描述
 
  如果有一个新数据45要被写入缓存,但此时已经没有缓存空间了,也就是链表没有空余位置了,那么LRU算法会做两件事情:数据45是刚被访问的,所以它会被放到MRU端;算法把LRU端的数据5从缓存中删除,相应的链表中就没有数据为5的数据了。LRU认为刚刚被访问过的数据,肯定会被再次访问,所以就把它放在MRU端;长久不访问的数据,肯定不会再访问了,所以就让它后移到LRU端,当缓存满时,就优先删除它。

但是LRU算法会出现几个问题:
  LRU算法在实际实现时,需要用链表管理所有的缓存数据,移除元素时直接从链表的队尾移除,增加时增加到头部就可以了,但是这会带来额外的空间开销。而且,当有数据被访问时,需要在链表上把数据移动到MRU端,由于是链表,虽然这个开销比较小,但是如果有大量数据被访问,那么就会带来很多链表移动的操作了,而且会减低Redis缓存性能

  所以,Redis并没有直接使用原汁原味的LRU算法,而是对LRU算法做了优化,解决了上面的问题,减少了数据淘汰对缓存性能的影响。具体来说:
1、Redis 默认会记录每个数据的最近异常访问的时间戳(在一个数据结构中 RedisObject 中Iru字段来记录)
2、然后,Redis 在决定淘汰数据时,第一次会随机选出N个数据,把他们作为一个候选集合。接下来,Redis会比较这N个数据的 Iru字段,把 Iru 字段的最小的数据从缓存中淘汰出去。
3、当再次需要淘汰数据时,Redis 需要挑选数据进入之前创建的候选集合,然后再次进行比较,这里的比较标准是:能进入候选集合数据的 Iru 字段值必须小于候选集合中最小的 Iru 值。当有新的数据进入候选集合后,如果候选集合数据的个数已经达到了N个,Redis 就把候选数据集中的 Iru 字段最小的数据淘汰出去。

  这样一来,Redis 缓存就不用为所有的数据维护一个大链表,也不用在每次数据访问时都移动链表项,提升了缓存的性能。

  同时,Redis 提供了一个日志参数 maxmory-samples ,这个参数就是 Redis 选出的数据个数N。例如,我们执行如下命令,就可以让 Redis 选出100个数据作为候选数据集:

config set maxmemory-samples 100

 
 

LFU 算法的引入

  LRU对于热点数据来说实际上并不是那么精准,比如下面的情况“|”表示删除,在距离我们删除的时候,如果我们使用LRU算法,遵循最近最少使用,那么在 A 和 D 之中,A会先被删除,但是实际上A的使用频率要比D频繁,所以合理的淘汰策略一个是淘汰D,而LFU最近最不频繁使用算法就是为了应对这种情况而生的。

~~~~~A~~~~~A~~~~~A~~~~A~~~~~A~~~~~A~~|
~~~~~D~~~~~~~~~~D~~~~~~~~~D~~~~~~~~~D|

2、LFU(least Frequently Userd最近最不频繁使用)

  LFU算法是在Redis4.0之后出现的,它的核心思想是根据 key 的最近访问的频率进行淘汰,很少被访问的优先被淘汰,被访问多的则被留下来。LFU算法比起LRU算法来说能更好的标识一个 Key 被访问的热度。我们再举个例子,如果我们使用LRU算法来探测热点数据,一个 key 很久没有被访问到,只是刚刚偶尔被访问到了一次,那么它就认为是热点数据,不会被淘汰,而有些 key 将来可能被访问到的却被淘汰了。如果我们使用了LFU算法则不会出现这种情况,因为使用一次并不会使用过 key 成为热点数据。LRU关注最后一次访问的时间,淘汰离现在最久的。LFU关注使用次数,淘汰使用次数最少的。

但是LFU的实现比LRU更为复杂,它需要考虑几个问题:

  • 如果实现为链表,当对象被访问时安装访问次数移动到链表的某个位置可能是低效的,因为可能存在大量访问次数相同的key。
  • 某些 key的访问次数可能非常大,理论上可以无限大,单实际上我们并不需要精确的访问次数。
  • 访问次数特别大的 key可能之后都不再访问了,但是因为访问次数大而占用着内存不被淘汰,需要一个方法来逐步衰减次数。

奇妙的是 Redis 只用了 24bit 就来记录上述信息,注意是 bit ,其中这 24bit 中,16bit 用于存放上一次的递减时间(解决第三个问题),用剩下的 8bit 来存放访问次数(解决第二个问题)

 
 
 
  
  
  

相关文章:

Redis过期删除策略

目录引出Redis过期删除策略Redis的两种过期策略:定期删除 惰性删除定期删除惰性删除Redis两种过期删除策略存在的问题Redis缓存淘汰策略Redis中的LRU和LFU算法1、LRU(Least Recently Userd最近最少使用)LFU 算法的引入2、LFU(lea…...

数据流分析之def-use链分析

数据流分析之def-use链分析引言1 相关概念2 算法2.1 算法规则2.2 算法流程2.3 算法优化3 举例引言 编译过程中,知道函数中每个指令引用的变量(或虚拟寄存器)来自于前面的哪一次赋值是很有必要的。例如llvm中对store/load转phi优化,就需要准确知道该信息…...

【0175】【内存上下文】如何利用context_freelists[]来彻底释放MemoryContext中分配的所有内存(8 - 2)

文章目录 1. MemoryContext 删除的另一种形式1.1 context_freelists[] 数组1.1.1 context_freelists[0] 和 context_freelists[1] 的意义1.1.2 context_freelists[0] 和 context_freelists[1] 各自功能示意图1.2 context_freelists[] 各成员在删除context时的初始化情况1.2.1 c…...

Redis实战—黑马点评(一) 登录篇

Redis实战 — 黑马点评(一) 登录篇 来自黑马的redis课程的笔记 【黑马程序员Redis入门到实战教程,深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目】 目录Redis实战 — 黑马点评(一) 登录篇1. 项目…...

建造者模式-搭建Qt窗口案例

文章目录logging日志输出子线程设计模式可视化插件类界面设计呼吸灯实现综合案例实现本综合案例,应用到如下的知识点。logging日志输出 自定义日志记录器,实现将日志输出到指定的控件中。 # 自定义日志记录器类子线程 threading实现子线程及Qt中的子线…...

*from . import _imaging as core : ImportError: DLL load failed: 找不到指定的模块

错误提示如上。为了解决这个问题,首先参考了解决 from . import _imag…模块。. 首先尝试了彻底卸载pillow:conda uninstall pillow ; pip uninstall pillow 然后重装 pip install pillow,发现问题仍然没有解决。 并且尝试了windo…...

关于尚硅谷Hadoop-报错解决方案日志

以后都会将学习Hadoop中遇到的问题写到这里,供自己参考,能帮到大家更好SecondaryNameNode未启动解决办法:可能是端口被占用(我没遇到)hadoop104未在/etc/hosts配置映射路径我在hadoop104的/etc/hosts 添加了所有hadoop…...

前端高频面试题-HTML和CSS篇(二)

💻 前端高频面试题-HTML和CSS篇(二) 🏠专栏:前端面试题 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向…...

神经网络损失函数分布可视化神器

论文名称和地址:Visualizing the Loss Landscape of Neural Netshttps://arxiv.org/pdf/1712.09913.pdf1.1 背景和动机作者主要想研究几个问题:为什么我们能够最小化高度非凸神经损失函数?为什么得到的最小值这个结果具有泛化性?不…...

ansible的部署与命令模块

目录 一、ansible的概述 1、ansible简介 2、ansible特点 3、官方网站 4、ansible的模块组成 5、ansible的工作机制 二、ansible部署 1、ansible的安装 三、ansible的命令行模块 1、command模块 2、shell模块 3、cron模块 4、user模块 5、group模块 6、copy模块 7…...

开发人员与测试人员关系的理解

在软件开发中都会有开发人员(以下简称开发)和测试人员(以下简称测试),在一些小型公司可能并没有测试,仅仅是开发兼任测试。在这里我仅针对于有专业的测试和专业的开发的项目。 每个公司应该都有考核机制&am…...

直面原理:5 张图彻底了解 Android TextToSpeech 机制

ChatGPT 如此火爆,但它的强悍在于 NLU(自然语言理解)、DM(对话管理)和 NLG (自然语言生成)这三块,而 Recognition 识别和 TTS 播报这两块是缺失的。假使你的 App 接入了 ChatGPT&…...

Ruby Socket 编程

Ruby提供了两个级别访问网络的服务,在底层你可以访问操作系统,它可以让你实现客户端和服务器为面向连接和无连接协议的基本套接字支持。 Ruby 统一支持应用程序的网络协议,如FTP、HTTP等。 不管是高层的还是底层的。ruby提供了一些基本类&a…...

Vue3+ElementPlus+koa2实现本地图片的上传

一、示例图二、实现过程利用Koa2书写提交图片的后台接口这个模块是我写的项目中的其中一个板块——上传图片,这个项目的后台接口主要是是使用了后端的Koa2框架,前端小伙伴想要试着自己书写一些增删改查的接口可以从这个入手,Koa2用来了解后端…...

常见漏洞之 Fastjson

数据来源 01 Fastjson相关介绍 》Fastjson概述 》Fastjson历史漏洞 02 Fastson的识别与漏洞发现 》Fastjson寻找 》Fastjson漏洞发现(利用 dnslog) 03 修复建议 建议1:使用fastjson1.2.83版本; Github地址:https:…...

绕过Nginx Host限制

目录绕过Nginx Host限制SNI第三种方法:总结绕过Nginx Host限制 SNI SNI(Server Name Indication)是 TLS 的扩展,这允许在握手过程开始时通过客户端告诉它正在连接的服务器的主机名称。 作用:用来解决一个服务器拥有…...

Visual Studio 2022 常用快捷键,记录一下别忘记~

Visual Studio 2022 常用快捷键,记录一下别忘记~ CtrlEC 注释代码 CtrlEU 取消注释代码 CtrlED 格式化全部代码 CtrlShiftA 新建类 CtrlRG 删除无效Using CtrlH 批量替换 CtrlG 跳转到指定行 CtrlEE 在交互窗口中运行选中代码(很实用) AltEnter 快速引用 …...

软件测试回顾---重点知识

软件测试重点知识回顾 8.1.1软件测试的目的是 尽可能的发现程序中的错误并不是发现所有的错误并不是证明程序是错误的也不是为了调试程序8.1.2白盒测试根据什么设置测试用例?黑盒测试根据什么设置测试用例? 白盒测试根据内部逻辑来设计的黑盒测试根据的是…...

2D图像处理:2D Shape_Base_Matching_缩放_旋转_ICP_显示ROI

文章目录 调试结果参考调试说明问题0:并行运行问题问题1:模板+Mask大小问题问题2:组合缩放和旋转问题3:可以直接将计算边缘的代码删除问题4:如何在原始图像上显示匹配到的ROI问题5:计算的原始旋转角度不需要判断,直接可以在ICP中使用问题6:绘制坐标轴问题7:绘制ROI调试…...

HTTP、HTTPS

目录 1.HTTP 1.1.概述 1.2.报文结构 1.2.1.请求报文 1.2.2.响应报文 1.3.方法 2.HTTPS 1.HTTP 1.1.概述 HTTP,超文本传输协议,WEB体系选用了该协议作为应用层协议。 1.2.报文结构 1.2.1.请求报文 HTTP的请求报文(request&#xff0…...

计算机网络之http03:HTTPS RSA握手解析

不同的秘钥交换算法,握手过程可能略有差别 上文对HTTPS四次握手的学习 SSL/TLS Secure Sockets Layer/Transport Layer Security 协议握手过程 四次通信:请求服务端公钥 2次 秘钥协商 2次 (1)ClientHello请求 客户端向服务端发送client…...

一款针对EF Core轻量级分表分库、读写分离的开源项目

更多开源项目请查看:一个专注推荐.Net开源项目的榜单 在项目开发中,如果数据量比较大,比如日志记录,我们往往会采用分表分库的方案;为了提升性能,把数据库查询与更新操作分开,这时候就要采用读写…...

Linux环境变量讲解

目录 环境变量 alias命令 type命令 变量分类 Linux最主要的全局环境变量 环境变量 变量是计算机系统用于保存可变数值的数据类型 在Linux中,一般变量都是大写,命令是小写 在Linux中,变量直接使用,不需要定义(更快…...

iptables和nftables的使用

文章目录前言iptable简介iptable命令使用iptables的四表五链nftables简介nftables命令的时候nftables与iptables的区别iptables-legacy和iptables-nft实例将指定protocol:ip:port的流量转发到本地指定端口前言 本文展示了,iptables和nftable命令的使用。 # 实验环…...

中小学信息学相关编程比赛清单及报名网站汇总(C++类)

1、NOI系列比赛(CSP-J CSP-S NOIP NOI APIO CTSC IOI ISIJ等) NOI官网 NOI全国青少年信息学奥林匹克竞赛https://www.noi.cn/ 2、蓝桥杯青少年创意编程大赛 https://www.lanqiaoqingshao.cn/home 3、中国电子协会考评中心...

06Makefile

Makefile 1、Makefile简介 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂…...

【C++】模板初阶

🍅讨厌废话,直接上车 ☃️1.泛型编程 void Swap(int& left, int& right) { int temp left; left right; right temp; } void Swap(double& left, double& right) { double temp left; left right; right temp; } void Swap(char&…...

vue+nodejs考研资料分享系统vscode - Visual Studio Code

前端技术:nodejsvueelementui,视图层其实质就是vue页面,通过编写vue页面从而展示在浏览器中,编写完成的vue页面要能够和控制器类进行交互,从而使得用户在点击网页进行操作时能够正常。 Express 框架于Node运行环境的Web框架, 目 …...

LeetCode_单周赛_332

6354. 找出数组的串联值 题意 将数组首尾元素接在一起,就是串联值。 串联之后删除,如果只剩下一个元素,加上这个元素即可 双指针,从首和尾向中间移动即可 code **注意:**用 long 没看题目用了 int wa了一发 clas…...

[LeetCode周赛复盘] 第 332 场周赛20230212

[LeetCode周赛复盘] 第 332 场周赛20230212 一、本周周赛总结二、 [Easy] 6354. 找出数组的串联值1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6355. 统计公平数对的数目1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6356. 子字符串异或查询1. 题目描述2. 思路分析3. 代…...

柳州团购网站建设/关键词排名优化报价

对于高性能计算机,我的认识基本就是前面那篇对硬件的看法,我的看法可以归结为,电子计算机,神经网络计算机,量子计算机。转载于:https://blog.51cto.com/2326657/1184192...

浙江网站建设哪家专业/百度提交入口网址是什么

1. 概述 目前主流的是git作为自己代码管理,但是采用github需要付费才能够使用,如果不付费,代码需要公开。创业团队及小型开发团队都有必要搭建自己的代码服务器,自己摸索需要一定的时间,会赶不及项目进度。在此作者把自…...

微信小程序设计网站/企业营销型网站策划

上次我们讨论了静态的NAT,发现静态NAT并不能起到节约IP地址的作用,那么静态NAT存在的意义是什么呢? 我们看下面的拓扑 公司的一个员工,要在家里面来访问公司内部的资源,那么想实现这个目的,通过***我们可以…...

涞源县住房和城乡建设局网站/财经新闻每日财经报道

CREATE DATABASE TestDB ON ( FILENAME D:\TestDB.mdf --路径 ) for ATTACH_REBUILD_LOG...

长沙装修公司名单/抖音seo培训

几十~几百人规模的小公司,业务、研发、产品、市场等等角色的沟通成本并不是特别高。在公司创业早期,一个人身兼数职,沟通成本就更低了。有事情,大家拉到会议室,简单学一下金字塔原理,碰到问题很快就能得到解…...

想在网站上放百度广告怎么做/网站设计流程

COCO数据集官网:http://cocodataset.org/#download $ wget -c 网址 其中,加上-c的意思是断点续传。 如果你们的网络很慢,可以考虑在晚上没人的时候下载。 train2017:http://images.cocodataset.org/zips/train2017.zip val2017…...