Redis过期删除策略和内存淘汰策略

1、设置Redis键过期时间

  Redis提供了四个命令来设置过期时间(生存时间)。

EXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 秒。

PEXPIRE <key> <ttl> :表示将键 key 的生存时间设置为 ttl 毫秒。

EXPIREAT <key> <timestamp> :表示将键 key 的生存时间设置为 timestamp 所指定的秒数时间戳。

PEXPIREAT <key> <timestamp> :表示将键 key 的生存时间设置为 timestamp 所指定的毫秒数时间戳。

  PS:在Redis内部实现中,前面三个设置过期时间的命令最后都会转换成最后一个PEXPIREAT 命令来完成。

  补充知识点:

1.1、除了string独有设置过期时间的方法,其他类型都需依靠expire方法设置时间

# 字符串独有方式
setex/setNx(String key, int seconds, String value)

PERSIST <key> :表示将key的过期时间移除。

设置key的过期时间。超时后,将会自动删除该key。在Redis的术语中一个key的相关超时是volatile的。

生存时间可以通过使用DEL命令来删除整个 key 来移除,或者被SET 和GETSET命令覆写(overwrite)。这意味着,如果一个命令只是修改(alter)一个带生存时间的 key 的值而不是用一个新的 key 值来代替(replace)它的话,那么生存时间不会被改变。 如使用 INCR 递增key的值,执行 LPUSH 将新值推到 list 中或用 HSET 改变hash的field,这些操作都使超时保持不变。

  • 使用 PERSIST 命令可以清除超时,使其变成一个永久key
  • 若 key 被 RENAME 命令修改,相关的超时时间会转移到新key
  • 若 key 被 RENAME 命令修改,比如原来就存在 Key_A,然后调用 RENAME Key_B Key_A 命令,这时不管原来 Key_A 是永久的还是设为超时的,都会由Key_B的有效期状态覆盖

注意,使用非正超时调用 EXPIRE/PEXPIRE 或具有过去时间的 EXPIREAT/PEXPIREAT 将导致key被删除而不是过期(因此,发出的key事件将是 del,而不是过期)

1.2、返回键的剩余生存时间

TTL <key> :以秒的单位返回键 key 的剩余生存时间。

PTTL <key> :以毫秒的单位返回键 key 的剩余生存时间。

2、Redis过期时间的判定

  在Redis内部,每当我们设置一个键的过期时间时,Redis就会将该键带上过期时间存放到一个过期字典中。当我们查询一个键时,Redis便首先检查该键是否存在过期字典中,如果存在,那就获取其过期时间。然后将过期时间和当前系统时间进行比对,比系统时间大,那就没有过期;反之判定该键过期。

3、过期删除策略

  通常删除某个key,我们有如下三种方式进行处理。

①、定时删除

  在设置某个key 的过期时间同时,我们创建一个定时器,让定时器在该过期时间到来时,立即执行对其进行删除的操作。

  优点:定时删除对内存是最友好的,能够保存内存的key一旦过期就能立即从内存中删除。

  缺点:对CPU最不友好,在过期键比较多的时候,删除过期键会占用一部分 CPU 时间,对服务器的响应时间和吞吐量造成影响。

②、惰性删除

  设置该key 过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

  优点:对 CPU友好,我们只会在使用该键时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查。

  缺点:对内存不友好,如果一个键已经过期,但是一直没有使用,那么该键就会一直存在内存中,如果数据库中有很多这种使用不到的过期键,这些键便永远不会被删除,内存永远不会释放。从而造成内存泄漏。

③、定期删除

  每隔一段时间,我们就对一些key进行检查,删除里面过期的key。

  优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。另外定期删除,也能有效释放过期键占用的内存。

  缺点:难以确定删除操作执行的时长和频率。

     如果执行的太频繁,定期删除策略变得和定时删除策略一样,对CPU不友好。

     如果执行的太少,那又和惰性删除一样了,过期键占用的内存不会及时得到释放。

     另外最重要的是,在获取某个键时,如果某个键的过期时间已经到了,但是还没执行定期删除,那么就会返回这个键的值,这是业务不能忍受的错误。

4、Redis过期删除策略

  前面讨论了删除过期键的三种策略,发现单一使用某一策略都不能满足实际需求,聪明的你可能想到了,既然单一策略不能满足,那就组合来使用吧。

  没错,Redis的过期删除策略就是:惰性删除和定期删除两种策略配合使用。

  惰性删除:Redis的惰性删除策略由 db.c/expireIfNeeded 函数实现,所有键读写命令执行之前都会调用 expireIfNeeded 函数对其进行检查,如果过期,则删除该键,然后执行键不存在的操作;未过期则不作操作,继续执行原有的命令。

  定期删除:由redis.c/activeExpireCycle 函数实现,函数以一定的频率运行,每次运行时,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键。

  注意:并不是一次运行就检查所有的库,所有的键,而是随机检查一定数量的键。

  定期删除函数的运行频率,在Redis2.6版本中,规定每秒运行10次,大概100ms运行一次。在Redis2.8版本后,可以通过修改配置文件redis.conf 的 hz 选项来调整这个次数。

  

  看上面对这个参数的解释,建议不要将这个值设置超过 100,否则会对CPU造成比较大的压力。

  我们看到,通过过期删除策略,对于某些永远使用不到的键,并且多次定期删除也没选定到并删除,那么这些键同样会一直驻留在内存中,又或者在Redis中存入了大量的键,这些操作可能会导致Redis内存不够用,这时候就需要Redis的内存淘汰策略了。

5、内存淘汰策略

①、设置Redis最大内存

  在配置文件redis.conf 中,可以通过参数 maxmemory <bytes> 来设定最大内存:  

  不设定该参数默认是无限制的,但是通常会设定其为物理内存的四分之三。(这里有个疑惑:为啥作者不考虑将此参数设定为百分比呢?)

②、设置内存淘汰方式

  当现有内存大于 maxmemory 时,便会触发redis主动淘汰内存方式,通过设置 maxmemory-policy ,有如下几种淘汰方式:

  1)volatile-lru   利用LRU算法移除设置过过期时间的key (LRU:最近最少使用 Least Recently Used ) 。

  2)allkeys-lru   利用LRU算法移除任何key (和上一个相比,删除的key包括设置过期时间和不设置过期时间的)。通常使用该方式

  3)volatile-random 移除设置过过期时间的随机key 。

  4)allkeys-random  无差别的随机移除。

  5)volatile-ttl   移除即将过期的key(minor TTL) 

  6)noeviction 不移除任何key,只是返回一个写错误 ,默认选项,一般不会选用。

  在redis.conf 配置文件中,可以设置淘汰方式:

  

6、总结

  通过上面的介绍,相信大家对Redis的过期数据删除策略和内存淘汰策略有一定的了解了。这里总结一下:

  Redis过期删除策略是采用惰性删除和定期删除这两种方式组合进行的,惰性删除能够保证过期的数据我们在获取时一定获取不到,而定期删除设置合适的频率,则可以保证无效的数据及时得到释放,而不会一直占用内存数据。

  但是我们说Redis是部署在物理机上的,内存不可能无限扩充的,当内存达到我们设定的界限后,便自动触发Redis内存淘汰策略,而具体的策略方式要根据实际业务情况进行选取。

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

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

相关文章

flutter怎么对ReorderableListView中的用于排序的控制手柄进行显示或隐藏

我在使用ReorderableListView创建可排序列表的时候&#xff0c;需要在编辑的时候才显示右侧的控制排序的手柄。研究了半天&#xff0c;配合搜索引擎&#xff0c;才找到正确的方案。 答案很简单&#xff0c;就是在它的属性当中有一个叫做&#xff1a;buildDefaultDragHandles的…

SICP : The Elements of Programming

好的计算机编程语言应具备的三个特性 基础单元表达式&#xff0c;计算机编程语言最最最基础单元&#xff0c;理应具备的表达式组合的能力&#xff0c;能够通过基础单元表达式组合成更复杂的元素抽象的能力&#xff0c;能通过复杂的元素抽象成更高层的单元 基础单元表达式 加 …

计算机硬件 4.2显卡

第二节 显卡 一、基本概念 1.定义&#xff1a;是主机与显示器之间的接口电路&#xff0c;也成为显示适配器&#xff0c;决定显示系统的优劣。 2.作用&#xff1a;处理和存储图形数据&#xff0c;向显示器提供信号、控制显示器显示的重要设备。 3.分类&#xff1a;核芯显卡、…

lvgl 双物理显示器的驱动实现

目录 一、背景 1. 要实现的功能2. lvgl 版本 二、简单粗暴的方式 理论上可以这样实现缺陷&#xff1a; 三、lvgl 自身机制支持 3.1 实现思路3.2 初始化缓冲区和注册显示驱动 3.2.1 复制lv_port_disp → lv_port_disp_23.2.2 修改 lv_port_disp_2 文件3.2.3 在应用层调用显示器…

什么是SLAM中的回环检测,如果没有回环检测会怎样

目录 什么是回环检测 如果没有回环检测 SLAM&#xff08;Simultaneous Localization and Mapping&#xff0c;即同时定位与地图构建&#xff09;是一种使机器人或自动驾驶汽车能够在未知环境中建立地图的同时定位自身位置的技术。回环检测&#xff08;Loop Closure Detectio…

快速入门学习定时任务框架-xxljob

定时任务框架-xxljob 简介 主要用于分布式任务调度&#xff0c;可以将任务调度和执行分布在多个节点上。它提供了一个集中式的管理平台&#xff0c;支持动态添加、修改、删除任务&#xff0c;以及任务的分片执行&#xff0c;确保任务在分布式环境中的高可用性的一个框架 spr…

C语言中函数调用和嵌套

函数是C语言的基本组成元素 函数调用 根据函数在程序中出现的位置有下列三种函数调用方式&#xff1a; 将函数作为表达式调用 将函数作为表达式调用时&#xff0c;函数的返回值参与表达式的运算&#xff0c;此时要求函数必须有返回值 int retmax(100,150); 将函数作为语句…

k8s学习 — (DevOps实践)第十四章 微服务 DevOps 实战 【Kubesphere DevOps】

k8s学习 — &#xff08;DevOps实践&#xff09;第十四章 微服务 DevOps 实战 【Kubesphere DevOps】 1 开启 DevOps2 集成 SonarQube3 更新 settings.xml4 部署项目4.1 Spring Boot 项目4.1.1 项目4.1.2 配置文件 4.2 微服务项目4.2.1 项目4.2.2 配置文件 5 DevOps 项目5.1 Sp…

大数据Doris(四十一):物化视图简单介绍

文章目录 物化视图简单介绍 一、适用场景

Windows系统配置pytorch环境,Jupyter notebook编辑器安装使用(深度学习本地篇)

如今现在好一点的笔记本都自带英伟达独立显卡&#xff0c;对于一些简单的深度学习项目&#xff0c;是不需要连接服务器的&#xff0c;甚至数据量不大的话&#xff0c;cpu也足够进行训练学习。我把电脑上一些以前的笔记整理一下&#xff0c;记录起来&#xff0c;方便自己35岁事业…

在Android中使用Flow获取网络连接信息

在Android中使用Flow获取网络连接信息 如果你是一名Android开发者&#xff0c;你可能会对这个主题感到有趣。考虑到几乎每个应用程序都需要数据交换&#xff0c;例如刷新动态或上传/下载内容。而互联网连接对此至关重要。但是&#xff0c;当用户的设备离线时&#xff0c;数据如…

Python之__enter__和__exit__

1. 概述 这两个函数与with as语句语句紧密相连&#xff0c;即 class Test():def __enter__(self):print("Enter!")passdef __exit__(self, type, value, trace):print("Exit!")passwith Test() as f: # 执行with as语句时&#xff0c;Test类中的_…

git中的smart checkout和force checkout

切换分支时出现了这个问题&#xff1a; 这是因为shiyan01分支修改了代码,但是没有commit, 所以在切换到test分支的时候弹出这个窗口 一、smart checkout(智能签出) 会把shiyan01分支的改动内容带到test分支。合并处理后的内容就变成了test分支的内容,而shiyan01分支的改动会被…

【Qt-编码】

Qt编程指南 ■ 编码■ ASCII■ ANSI■ GB2312■ GBK■ GB18030 编码■ Unicode■ UTF-8&#xff1a; ■ Qt接收注射泵GBK编码后显示乱码■■ ■ 编码 ■ ASCII &#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff09;…

LH7904D 太阳能警示灯 0.4W×2

应用范围: 可安装在电线杆&#xff0c;路灯&#xff0c;围挡&#xff0c;交 通护栏及各种杆式固体等场所起警示作用。 产品特点&#xff1a; 采用进口PS材质; 光控无开关&#xff0c;白天不闪&#xff0c;昏暗环境自动闪烁&#xff0c;无需手动操作&#xff0c;省时省事; …

L4S 杂谈

这不是技术文档&#xff0c;这是技术以外的文档。 带宽资源越来越丰富时&#xff0c;大家反而不抢了&#xff0c;资源越稀缺争抢越厉害&#xff0c;相比丰盈的带宽&#xff0c;如今人们更关注时延。l4s 提供了完全不同的方案。但梳理一下传统方法是必要的。 30 多年来&#x…

SpringBoot Gateway整合过程中的问题

现象描述&#xff1a; 第一次请求正常&#xff0c;第二次报错&#xff0c;错误如下&#xff1a; 2023-12-25 00:47:46.928 ERROR 5484 --- [ctor-http-nio-6] a.w.r.e.AbstractErrorWebExceptionHandler : [34ab38d8-2] 500 Server Error for HTTP GET "/gateway/config…

Oracle 学习(2)

过滤和排序数据 where条件过滤 日期格式 查询10号部门的员工信息&#xff1a;SQL> select * from emp where deptno10 查询”KING”的信息&#xff1a;SQL> select * from emp where ename KiNg 未选定行。 注意&#xff1a;字符串大小写敏感。 SQL> selec…

Navicat误删除生产环境SQLServer2012单表数据后恢复单表数据

背景&#xff1a; 1-后端更新功能部署到客户生产环境时误将测试环境数据保留&#xff0c;项目负责人发现后告知后端。 2-后端登录客户生产数据库使用navicat删除一张表的单表数据时多删了几条数据&#xff0c;判断弄乱了客户生产环境下自己产生的单表数据。 思路&#xff…

直通车定义、功能以及扣费原则

1.直通车是天猫付费搜索广告&#xff0c;即时需求&#xff0c;是消费者主动来搜索的&#xff0c;cpc扣费原则&#xff0c;一般用来拉新或者收割客户&#xff1b; 2.一般关键词优先&#xff0c;人群溢价是用来更精准投放的&#xff0c;可以不投溢价人群&#xff1b; 3.溢价人群…