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 需要实现在其他组件中使用同一个子组件。 子组件 子组件(所谓子组件…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
