Redis过期删除策略

news2024/11/15 12:40:48

目录

    • 引出
    • 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 来存放访问次数(解决第二个问题)

 
 
 
  
  
  

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

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

相关文章

Netty 组件学习

Netty 组件学习Netty 各个组件通俗理解EventLoopEventLoopGroup关闭ChannelFuture & PromiseHandler & PipelineByteBuf创建直接内存和堆内存池化和非池化组成方法扩容机制读取retain和release方法Netty 各个组件通俗理解 Channel即数据通道 Msg是数据,传…

对KMP简单的理解

声明:下边的例子均表示下标从1开始的数组 ne数组的定义: next[i] 就是使子串 s[1…i] 有最长相等前后缀的前缀的最后一位的下标。ne[i]也可以表示相等子串的长度 准备执行jne[j]时, 表示当前s[i]!p[j1] , 如果ne[j]1 ,那么下…

Dubbo和Zookeeper集成分布式系统快速入门

文件结构 代码部分 1、新建provider-server导入pom依赖 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</version></dependency><dependency>&l…

golang的web框架Gin(一)---Gin的安装与初体验

简介 1.1 介绍 Go世界里最流行的Web框架&#xff0c;Github上有32Kstar。 基于httprouter开发的Web框架。 中文文档齐全&#xff0c;简单易用的轻量级框架。 Gin是一个golang的微框架&#xff0c;封装比较优雅&#xff0c;API友好&#xff0c;源码注释比较明确&#xff0c;具有…

C++模板初阶

C模板初阶泛型编程函数模板概念函数模板格式函数模板原理函数模板的实例化模板参数的匹配原则类模板类模板的定义格式类模板的实例化泛型编程 我们前面学习了C的函数重载功能&#xff0c;那么我们如何实现一个通用的交换函数呢&#xff0c;比如:我传入int就是交换int&#xff…

JavaSE XML语法规则和文档约束介绍

文章目录XMLXML基本介绍XML创建和语法规则XML文档约束认识文档约束DTD约束(了解)schema约束(了解)XML XML基本介绍 XML概述: XML是可扩展标记语言&#xff08;eXtensible Markup Language&#xff09;的缩写&#xff0c;它是一种可以自定义数据的表示格式&#xff0c;可以描述…

【mysql数据库】

目录SQL数据库分页聚合函数表跟表之间的关联关系SQL中怎么将行转成列SQL注入将一张表的部分数据更新到另一张表WHERE和HAVING的区别索引索引分类如何创建及保存MySQL的索引&#xff1f;怎么判断要不要加索引&#xff1f;索引设计原理只要创建了索引&#xff0c;就一定会走索引吗…

ESP-01S通过AT指令上报数据到阿里云物模型

ESP-01S使用AT指令上报数据到阿里云物模型 上篇文章介绍了如何用AT指令连接阿里云并进行通信&#xff1a;https://blog.csdn.net/weixin_46251230/article/details/128995530 但最终需要将传感器数据上报到云平台显示&#xff0c;所以需要建立阿里云物模型 阿里云平台建立物…

代码随想录第62天(单调栈):● 739. 每日温度 ● 496.下一个更大元素 I

今天开启单调栈的篇章&#xff0c;一般什么时候采用单调栈&#xff1f;通常是一维数组&#xff0c;要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置。 一、每日温度 题目描述&#xff1a; 思路和想法&#xff1a; 这里单调栈里只放数组下标&#xff0c;再了…

删除Android Studio中重复的JDK配置

问题 可能因为一些不经意的操作&#xff0c;导致如下这种情况&#xff1a;出现多余重复的JDK路径配置&#xff0c;其实指向的是同一个路径。 强迫症犯了之后&#xff0c;就会想怎么干掉这个&#xff08;2&#xff09;。 解决 第一步&#xff1a;先打开你最近打开的项目&…

开篇之作——闲聊几句AUTOSAR(2)

开篇之作——闲聊几句AUTOSAR 我是穿拖鞋的汉子,魔都中坚持长期主义的工科男! 在上一篇文章中主要介绍了啥是AUTOSAR,AUTOSAR要干点啥,以及AUTOSAR的发展历史。接下来在本文中将继续介绍: -> AUTOSAR的合作伙伴关系; -> 组织架构; -> 基础标准规范。 言归正…

微信公众号网页在本地开发模式下如何使用正式环境的域名来调试

微信公众号网页在本地开发模式下如何使用正式环境的域名来调试&#xff1f; 鄙人之前也不知道&#xff0c;网上搜了一下&#xff0c;看到的几篇文章都是要使用代理&#xff0c;有用Nginx的&#xff0c;还有自己写代理的。主要是按照步骤做了并不行。于是自己折腾了一下&#x…

缓存中间件Caffeine超详细源码解读

读源码是一件非常复杂、困难、枯燥的过程&#xff0c;这个复杂过程我给大家踩了&#xff0c;各位看官躺平看就行啦初始化入口&#xff1a;//典型的工厂模式&#xff0c;初始化一个caffeine对象 Caffeine.newBuilder();CheckReturnValue public static Caffeine<Object, Obje…

(考研湖科大教书匠计算机网络)第四章网络层-第三节1:IPv4地址概述

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;IPv4地址概述二&#xff1a;IPv4地址表示方法&#xff08;1&#xff09;概述&#xff08;2&#xff09;8位无符号二进制数转十进制正整数&#xff…

大数据工具Maxwell的使用

1.Maxwell简介 Maxwell 是由美国Zendesk公司开源&#xff0c;用Java编写的MySQL变更数据抓取软件。它会实时监控Mysql数据库的数据变更操作&#xff08;包括insert、update、delete&#xff09;&#xff0c;并将变更数据以 JSON 格式发送给 Kafka、Kinesi等流数据处理平台。 官…

Elasticsearch7.8.0版本进阶——路由计算

目录一、路由计算1.1、路由计算的前提理解1.2、路由计算的概述1.3、路由计算的概述一、路由计算 1.1、路由计算的前提理解 当索引一个文档的时候&#xff0c;文档会被存储到一个主分片中。Elasticsearch 如何知道一个文档应该存放到哪个分片中呢&#xff1f;当我们创建文档时…

mycat连接mysql 简单配置

mycat三个配置文件位于conf下 可通过Notepad操作 首先配置service.xml中的user标签&#xff0c;设置用户名&#xff0c;密码&#xff0c;查询权限&#xff0c;是否只读等 只是设置了root用户&#xff0c;有所有权限 配置schema.xml <?xml version"1.0"?&g…

FPGA开发软件(vivado + modelsim)环境搭建(附详细步骤)

本文详细介绍了vivado软件和modelsim软件的安装&#xff0c;以及vivado中配置modelsim仿真设置&#xff0c;每一步都加文字说明和图片。一、软件安装包下载1、vivado vivado版本很多&#xff0c;目前最新的已更新到vivado2022.2&#xff0c;版本越高&#xff0c;安装包越大&…

PTA甲级-1010 Radix c++

文章目录Input Specification:Output Specification:Sample Input 1:Sample Output 1:Sample Input 2:Sample Output 2:一、题干大意![在这里插入图片描述](https://img-blog.csdnimg.cn/68d84d3ea86e4aaab002152ae8472e05.png#pic_center)二、题解要点三、具体实现总结Given a…

【呕心沥血】整理全栈自动化测试技术(三):如何编写技术方案

前面两篇笔记我介绍了自动化测试前期调研注意事项和前置准备阶段切入点&#xff0c;有同学在后台提问&#xff1a; “做完前期的调研和准备工作&#xff0c;领导要求写一个落地方案并评审&#xff0c;自动化测试的落地方案该怎么写”&#xff1f; 首先这个要求我觉得挺正常&a…