当前位置: 首页 > 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…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

React Native 导航系统实战(React Navigation)

导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...