Redis过期数据的删除策略

1 介绍

Redis 是一个kv型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量。
想要把不需要的数据清理掉,一种办法是直接删除,这个咱们前面章节有详细说过;另外一种就是设置过期时间,缓存过期后,由Redis系统自行删除。
这边需要注意的是,缓存过期之后,并不是马上删除的,那Redis是怎么删除过期数据的呢?主要通过两个方式

  • 惰性删除
  • 通过定时任务,定期选取部分数据删除

2 Redis缓存过期命令

我们通过以下指令给指定key的缓存设置过期时间,如果都没设置过期时间, key 将一直存在,直到我们使用 Del 的命令明确删除掉。

# 缓存时间过期命令,参考如下
EXPIRE key seconds [ NX | XX | GT | LT] 

Redis 7.0 开始,EXPIRE 添加了 NX、XX和GT、LT 选项,分别代表如下:

  • NX:仅当Key没有过期时设置过期时间
  • XX:仅当Key已过期时设置过期时间
  • GT:仅当新到期时间大于当前到期时间时设置到期时间
  • LT:仅当新到期时间小于当前到期时间时设置到期时间

其中,GT、LT和NX选项是互斥的,下面是官方的测试用例:

redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
"OK"
redis> TTL mykey
(integer) -1
redis> EXPIRE mykey 10 XX
(integer) 0
redis> TTL mykey
(integer) -1
redis> EXPIRE mykey 10 NX
(integer) 1
redis> TTL mykey
(integer) 10

3 两种过期数据的删除方式

我们前面说过,Redis删除过期数据主要通过以下两个方式,我们一个个来看:

  • 惰性删除
  • 通过定时任务,定期选取部分数据删除

3.1 惰性删除

惰性删除比较简单,当客户端请求过来查询我们的key的时候,先对key做一下检查,如果没过期则返回缓存数据,如果过期,则删除缓存,重新从数据库中获取数据。
这样,我们就把删除过期数据的主动权交给了访问请求的客户端,如果客户端一直没请求,那这个过期缓存可能就长时间得不到释放。

Redis的源码 src/db.c 中的 expireIfNeeded 方法 就是实现以上惰性删除逻辑的,我们来看看:

int expireIfNeeded(redisDb *db, robj *key, int force_delete_expired) {// 对于未过期的key,直接 return 0if (!keyIsExpired(db,key)) return 0;	/* If we are running in the context of a slave, instead of* evicting the expired key from the database, we return ASAP:* the slave key expiration is controlled by the master that will* send us synthesized DEL operations for expired keys.** Still we try to return the right information to the caller,* that is, 0 if we think the key should be still valid, 1 if* we think the key is expired at this time. */if (server.masterhost != NULL) {if (server.current_client == server.master) return 0;if (!force_delete_expired) return 1;}/* If clients are paused, we keep the current dataset constant,* but return to the client what we believe is the right state. Typically,* at the end of the pause we will properly expire the key OR we will* have failed over and the new primary will send us the expire. */if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;/* Delete the key */deleteExpiredKeyAndPropagate(db,key);return 1;
}

3.2 定期删除

刚才前面说过了,仅靠客户端访问来对过期缓存执行删除远远不够,因为有的 key 过期了,但客户端一直没请求,那这个过期缓存可能就长时间甚至永远得不到释放。
所以除了惰性删除,Redis 还可以通过定时任务的方式来删除过期的数据。定时任务的发起的频率由redis.conf配置文件中的hz来进行配置

# 代表每1s 运行 10次
hz 10

Redis 默认每 1 秒运行 10 次,也就是每 100 ms 执行一次,每次随机抽取一些设置了过期时间的 key(这边注意不是检查所有设置过期时间的key,而是随机抽取部分),检查是否过期,如果发现过期了就直接删除。
该定时任务的具体流程如下:

  1. 定时serverCron方法去执行清理,执行频率根据redis.conf中的hz配置的值
  2. 执行清理的时候,不是去扫描所有的key,而是去扫描所有设置了过期时间的key(redisDb.expires)
  3. 如果每次去把所有过期的key都拿过来,那么假如过期的key很多,就会很慢,所以也不是一次性拿取所有的key
  4. 根据hash桶的维度去扫描key,扫到20(可配)个key为止。假如第一个桶是15个key ,没有满足20,继续扫描第二个桶,第二个桶20个key,由于是以hash桶的维度扫描的,所以第二个扫到了就会全扫,总共扫描35个key
  5. 找到扫描的key里面过期的key,并进行删除
  6. 删除完检查过期的 key 超过 25%,继续执行4、5步

image

其他注意点:

  • 为何不扫描所有key进行过期缓存元素删除:Redis本身就是高速缓存,如果每次检查大量的key,无论在CPU和内存的的使用率上都会特别高,Redis集群越大,风险越大。
  • 分片模式下的删除同步:无论定时删除还是惰性删除。master 会生成删除的指令记录到 AOF 和 slave 节点。

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

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

相关文章

ubuntu18.04安装远程控制软件ToDest方法,针对官网指令报错情况

有时我们在家办公,需要控制实验室的笔记本,因此好用的远程控制软件会让我们的工作事半功倍! 常用的远程控制软件有ToDesk,向日葵,以及TeamViewer,但是为感觉ToDesk更流畅一些,所以这里介绍一下…

Python - 面向对象的属性,类方法,静态方法,实例方法的区别及用法详解

一. 前言 在Python的面向对象编程中,类属性和实例属性是两个不同的概念,它们在作用域和使用方式上有所区别。在Python中的面向对象编程中有三种方法:实例方法、类方法和静态方法,它们之间的差异主要体现在参数传递和调用方式上。…

Windows运行Spark所需的Hadoop安装

解压文件 复制bin目录 找到winutils-master文件hadoop对应的bin目录版本 全部复制替换掉hadoop的bin目录文件 复制hadoop.dll文件 将bin目录下的hadoop.dll文件复制到System32目录下 配置环境变量 修改hadoop-env.cmd配置文件 注意jdk装在非C盘则完全没问题,如果装在…

23种设计模式攻关

👍一、创建者模式 🔖1.1、单例模式 单例模式(Singleton Pattern),用于确保一个类只有一个实例,并提供全局访问点。 在某些情况下,我们需要确保一个类只能有一个实例,比如数据库连接…

leetcode 674. 最长连续递增序列

2023.8.24 与最长递增子序列 类似,不同的是, 本题要求连续序列,所以不需要第二层遍历比较之前所有的元素了,只需要比较上一个元素i-1。 dp[i]的含义为:以nums[i]元素为结尾的序列的最长递增子序列。 注意这里是以i为结…

Unity血条制作

一、使用UGUI制作血条 我一般使用image制作血条,当然,也可以使用滑动组件Slider。image的具体操作步骤如下 普通血条 1、在Hierarchy面板中,创建两个image组件,将其中一个设置为另外一个的子节点 2、在Inspector面板中&#…

酷开科技大屏营销,锁定目标人群助力营销投放

近日,中科网联发布《2023年中国家庭大屏白皮书》,数据显示智能电视近三年内使用人群增长平稳。全国4.94亿家庭户中,智能大屏渗透率近九成。不仅如此, CCData研究预测,2025年中国智能电视渗透率将达到95%以上。这与三年…

收单外包服务机构(第三方支付公司服务商)是什么?

收单外包服务机构(第三方支付公司服务商)是什么? 伴随着电子商务的迅速发展,越来越多的企业开始认识到收单外包服务机构的重要性。 收单外包是一个重要的服务机构,可以帮助企业解决许多与支付相关的问题。 收单外包服务…

【轴承故障诊断】用于轴承故障诊断的集中时频分析研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Golang GORM 单表删除

删除只有一个操作,delete。也是先找到再去删除。 可以删除单条记录,也可以删除多条记录。 var s Studentdb.Debug().Delete(&s, "age ?", 100)fmt.Println(s)[15.878ms] [rows:1] DELETE FROM student WHERE age 100var s Studentdb.De…

Compressor For Mac强大视频编辑工具 v4.6.5中文版

Compressor for Mac是苹果公司推出的一款视频压缩工具,可以将高清视频、4K视频、甚至是8K视频压缩成适合网络传输或存储的小文件。Compressor支持多种视频格式,包括H.264、HEVC、ProRes和AVC-Intra等,用户可以根据需要选择不同的压缩格式。 …

OAuth2.0 客户端实战

上一次课程,我们了解了 OAuth 认证是怎么回事,以及了解了四种认证方式,今天我们将以 Github 为例,了解一下如何用 Flask 第三方应用 在之前的介绍 JWT 的时候,了解过 Authlib 库,Authlib 是集 JWT、OAuth1…