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,而是随机抽取部分),检查是否过期,如果发现过期了就直接删除。
该定时任务的具体流程如下:
- 定时serverCron方法去执行清理,执行频率根据redis.conf中的hz配置的值
- 执行清理的时候,不是去扫描所有的key,而是去扫描所有设置了过期时间的key(redisDb.expires)
- 如果每次去把所有过期的key都拿过来,那么假如过期的key很多,就会很慢,所以也不是一次性拿取所有的key
- 根据hash桶的维度去扫描key,扫到20(可配)个key为止。假如第一个桶是15个key ,没有满足20,继续扫描第二个桶,第二个桶20个key,由于是以hash桶的维度扫描的,所以第二个扫到了就会全扫,总共扫描35个key
- 找到扫描的key里面过期的key,并进行删除
- 删除完检查过期的 key 超过 25%,继续执行4、5步
其他注意点:
- 为何不扫描所有key进行过期缓存元素删除:Redis本身就是高速缓存,如果每次检查大量的key,无论在CPU和内存的的使用率上都会特别高,Redis集群越大,风险越大。
- 分片模式下的删除同步:无论定时删除还是惰性删除。master 会生成删除的指令记录到 AOF 和 slave 节点。
相关文章:

Redis过期数据的删除策略
1 介绍 Redis 是一个kv型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量。 想要把不需要的数据清理掉,一种办法是直接删除,这个咱们前面章节有详细说过;另外一种就是…...

如何使用CSS实现一个拖拽排序效果?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 实现拖拽排序效果的CSS和JavaScript示例⭐ HTML 结构⭐ CSS 样式 (styles.css)⭐ JavaScript 代码 (script.js)⭐ 实现说明⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦…...

leetcode 118.杨辉三角
⭐️ 题目描述 🌟 leetcode链接:https://leetcode.cn/problems/pascals-triangle/description/ 代码: class Solution { public:vector<vector<int>> generate(int numRows) {// 先开空间vector<vector<int>> v;v.…...
微服务框架之SpringBoot面试题汇总
微服务框架之SpringBoot面试题汇总 什么是Spring Boot? 多年来,随着新功能的增加,spring变得越来越复杂。Spring项目,我们必须添加构建路径或添加Maven依赖关系,配置应用程序服务器,添加spring配置。因此&…...
Promise详解
目录 一、前言:为什么会出现Promise?二、Promise是什么?2.1 Promise的初体验 三、使用Promise的好处?3.1 指定回调函数的方式更加灵活3.2 可以解决回调地狱问题,支持链式调用 四、Promise实例对象的两个属性五、resolve函数以及reject函数六、Promise…...

Oracle 查询(当天,月,年)的数据
Trunc 在oracle中,可利用 trunc函数 查询当天数据,该函数可用于截取时间或者数值,将该函数与 select 语句配合使用可查询时间段数据 查询当天数据 --sysdate是获取系统当前时间函数 --TRUNC函数用于截取时间或者数值,返回指定的…...

什么是梯度下降
什么是梯度下降 根据已有数据的分布来预测可能的新数据,这是回归 希望有一条线将数据分割成不同类别,这是分类 无论回归还是分类,我们的目的都是让搭建好的模型尽可能的模拟已有的数据 除了模型的结构,决定模型能否模拟成功的关键…...

开黑啦kook 机器人开发 PHP swoole Liunx 服务器(宝塔)
安装环境 PHP 拓展 直接使用 宝塔一键安装 (Windows系统不支持) 设置命令行的PHP版本避免执行脚本时 获取不到 swoole 检查swoole是否安装成功 获取官方SDK GitHub - kaiheila/php-bot: 开黑啦机器人的php版本https://github.com/kaiheila/php-bot 配…...

Vue 中hash 模式与 history 模式的区别
hash 模式: - 地址中永远带着 # 号,不美观。 - 兼容性比较好。 - 通过手机 app 分享地址时,如果 app 效验严格,该地址会被标记为不合法。 history 模式: - 地址干净,美观。 - 兼容性和 hash 模式相比…...

Dockerfile推送私有仓库的两个案例
一,编写Dockerfile制作Web应用系统nginx镜像,生成镜像nginx:v1.1,并推送其到私有仓库。 具体要求如下: (1)基于centos基础镜像; (2)指定作者信息; ÿ…...

【指标】指标公式大全,款款经典(建议珍藏)!-神奇指标网
三、指标源码: 1、连续三天高开高走的选股公式 count(o〉ref(c,1)andc>o,3)3; 2、连续3天每天的最低价都比前一天高 count(l〉ref(c,1),3)3; 3、周量缩小50%或40%或n&#x…...
面试题目收集
Zset排行榜功能如何设计key? key就设计成排行榜的名字,比如下面插入或者更新数据 Long zadd(final String key, final double score, final String member) key : 排行榜的名字 memeber : 用户 score : 用户的分数 项目…...

创建R包-2.1:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)
目录 0-前言 1-在RStudio中创建R包项目 2-创建R包 2.1通过R函数创建新包 2.2在RStudio通过菜单来创建一个新包 2.3关于R包创建的说明 3-添加R自定义函数 4-添加C函数 0-前言 目标:在RStudio中创建一个R包,这个R包中包含C函数,接口是Rc…...

chatGPT如何解释泽众PerformanceRunner性能测试工具?
PerformanceRunner 是一个性能测试工具,可以帮助测试人员进行性能测试。它的主要功能包括: 1. 脚本录制和回放: PerformanceRunner可以录制 HTTP/HTTPS 通信协议的脚本,并能够回放模拟真实用户的行为。通过录制和回放,…...
LA@向量组线性相关性
文章目录 向量组线性相关性线性相关线性无关多向量向量组线性相关单向量向量组的线性相关性单位向量向量组线性相关性双向量向量组的线性相关性双向量线性相关的几何意义三向量线性相关的几何意义包含零向量的向量组线性相关概念迁移:线性方程组和线性相关齐次线性方程组和向量…...
[k8s] 基于ubuntu22部署k8s1.28记录
k8s1.28部署已经不依赖docker了,所以不需要安装docker。同理:如果想查看镜像和运行容器,也不能用docker命令去查询了:需要使用crictl。不过crictl命令参数兼容docker,所以使用上手没有啥难度。 1. 配置安装源 根据k8…...
React 事件代理 和原生事件绑定混用:你的选择会导致什么问题?
在React开发中,事件处理是一个常见的任务。React提供了一个方便的事件系统,但有时我们可能会在React组件中与原生DOM事件一起使用。本文将讨论React的事件代理机制与原生事件绑定混用可能导致的一些问题。 React的事件代理 React采用了一种称为"事…...
使用阿里云国外和国内云服务器有什么注意事项?
使用阿里云的国外和国内云服务器时,有一些注意事项需要考虑: 地理位置:选择离你的用户或数据中心最近的地理位置,可以减少延迟和提高访问速度。对于国内用户,使用国内云服务器可能更好;对于国外用户&#…...

【计算机网络】【常考问题总结】
1. ping 127.0.0.1 后会发生什么? ping 127.0.0.1 ;ping 0.0.0.0 ; ping localhost 面试官问:断网了,还能ping通 127.0.0.1 吗?为什么?_kevin_tech的博客-CSDN博客 2. MTU,MMU是…...

前端基础(props emit slot 父子组件间通信)
前言:如何实现组件的灵活使用,今天学习组件封装用到的props、slot和emit。 目录 props 子组件 父组件 示例代码 slot 示例代码 作用域插槽 emit 示例代码 props 需要实现在其他组件中使用同一个子组件。 子组件 子组件(所谓子组件…...

铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...