Redis 过期了解

Redis 版本:5.0 : 

一:过期监听:

Spring Data Redis 封装了 Redis 的 Pub/Sub 功能,提供了对 key 过期事件的监听支持。
1. 核心类:KeyExpirationEventMessageListener
这个抽象类是 Spring 提供的,专门用于监听 Redis 的 key 过期事件。
代码中的 RedisKeyExpiredListener 继承自它

Redis 的 key 过期事件是一种发布/订阅(Pub/Sub)机制,当某个设置了过期时间的 key 被 Redis 删除时,Redis 会发布一个事件通知。Spring 通过监听这些事件,并将其封装为 Spring 事件模型中的对象,从而实现对 key 过期事件的捕获和处理

Redis 的定期删除策略是 默认每秒执行 10 次(即每 100 毫秒运行一次),这是由 Redis 配置中的 hz 参数控制的。

实际上:默认配置中,hz=10,表示每秒运行 10 次过期键清理任务。
每次运行时,Redis 会从数据库中随机选取一批设置了过期时间的键进行检查,并删除其中已过期的键。
这个过程不会扫描所有键,因此可能会有部分过期键在过期后不会立刻被删除,导致“过期键延迟删除”

可以在 redis.conf 文件中调整 hz 参数来改变 Redis 清理过期键的频率:

增大 hz 值(例如设为 20 或 30)可以提高清理频率,从而提升过期键的删除实时性,但也会增加 CPU 消耗。
减小 hz 值则节省 CPU 资源,但可能导致更多的过期键滞留内存。 

实际操作也会遇到,手动更改了TTL方便更快过期,然后不刷新Redis Manager的情况下,尽管有定期删除策略,也没有收到那几个key的过期监听 

首先来认知原理:

Redis 使用两种策略来处理设置了 TTL 的键(即有过期时间的键):

删除策略触发方式是否会触发 expired 事件
惰性删除(Lazy Expiration)key 被访问时发现已过期但未被删除(惰性删除)✅ 会触发 expired 事件
定期删除(Active Expiration)Redis 每隔一段时间扫描并随机删除部分过期键❌ 不会触发 expired 事件

public class RedisKeyExpiredListener extends KeyExpirationEventMessageListener


这个类继承自 Spring Data Redis 提供的 KeyExpirationEventMessageListener。
它监听的是 Redis 的 __keyevent@*:expired 通道。
只有当 Redis 通过惰性删除触发过期事件时,才会向这个通道发布消息,从而触发你的 onMessage() 方法。 
如果一个 key 设置了过期时间(TTL),不主动访问它,也没有在过期后被 Redis 的惰性删除机制触发,那么你确实 可能永远收不到 expired 过期通知。

疑问?

如果 Redis 通过定期删除策略已经删除了一个设置了 TTL 的 key,此时再去手动 GET 这个 key,还会触发 Redis 的 expired 过期事件吗?
答:不会触发过期事件监听器(如 RedisKeyExpiredListener)

只有在访问一个 key 时,发现它已经过期但尚未被删除的情况下,才会真正执行删除操作,并触发 expired 事件。
但如果这个 key 已经被 Redis 的定期删除机制提前删掉了:
它已经不存在于 Redis 中;此时你再访问它(如 GET my_key),会直接返回 nil;
不会再次触发 Redis 的过期检查和事件通知。

二: 那么问题来了:什么是“查询”key?什么又是“访问”key?
2.1这是关键区分点 👇

操作是否算作“访问”
GET key✅ 是
EXISTS key✅ 是
TTL key✅ 是
DEL key✅ 是
Redis 内部线程检查 key 是否存在✅ 是
Redis 定期删除时只是遍历并比较过期时间❌ 不是

所以就是代码中有对Redis进行不定时的设置复合键的key时,就会访问key,这样不用直接去手动get 此key,一样是访问到了

key格式复合键:TEST_KEY:

redisTemplate.opsForValue().set(TEST_KEY+ relatedId , null ,60, TimeUnit.SECONDS);

使用这类代码,就是会导致,如果有进行定期set,就会访问key,从而触发一些过期key的过期监听收到消息,

如果不进行设置,则一些已经过期的就有可能被定时删除而收不到消息,导致消息丢失,数据不准确的问题

另外: Redis 定期删除到底做了什么?

Redis 使用了一个叫做 activeExpireCycle() 的函数来执行定期删除。
它的大致流程如下:

void activeExpireCycle(...) {// 获取当前数据库for (j = 0; j < dbs_per_call; j++) {for (k = 0; k < keys_per_call; k++) {// 随机选取一个设置了 TTL 的 keyif (currentExpiresTime < now()) {// 直接删除,不进行任何访问操作dbDelete(db, key);}}}
}

关键点
Redis 只检查 key 的过期时间;
没有真正访问这个 key 的内容(比如读取、修改等);
所以 不会触发惰性删除逻辑;

自然也就 不会发布 expired 事件。

2.2   除了上面说的情况,某些 key 即使没手动 get,也被监听到过期事件?

模块行为是否可能访问 key
Lua 脚本EVAL 中使用 key✅ 是
集群迁移MIGRATE 命令✅ 是
持久化RDB 快照生成时❌ 否
主从同步复制 key 到从节点❌ 否
慢日志记录慢命令❌ 否
其他业务模块如缓存统计、监控工具✅ 是

所以你虽然没有显式调用 get(key),但这些模块可能会在你不察觉的情况下访问 key,从而触发惰性删除。

三:Redis 淘汰策略中访问到这个 key

场景是否触发 expired 事件
Redis 定期删除直接删掉了这个 key❌ 否
Redis 主从同步时访问了这个 key✅ 是
Redis 集群迁移该 key 到新节点✅ 是
Redis 慢日志记录了访问该 key 的命令✅ 是(说明它已经被访问)
Redis 监控工具周期性检查 key✅ 是
Redis 淘汰策略中访问到这个 key✅ 是

所以,你的 key 是如何被访问到的?

机制是否可能访问 key
Redisson 的 RLock、RLock.tryLock()✅ 是
Spring Cacheable 缓存组件✅ 是
Redis 的 SCAN 命令✅ 是
Redis 的 KEYS * 命令✅ 是
Redis 的 EXPIRE 命令✅ 是
Redis 的 DEL 命令✅ 是

这些命令虽然你不写,但 Redis 内部模块或框架库可能会使用它们。

 四:使用 Redisson 的延迟队列(推荐)

RDelayedQueue<String> queue = redisson.getDelayedQueue(redisson.getQueue("my_queue"));
queue.offer("data", 60, TimeUnit.SECONDS);// 注册监听器
queue.registerListener(item -> {log.info("收到延迟消息: {}", item);
});

这种方式比依赖 Redis 的 expired 事件更加稳定可靠。

Redis 内部模块和后台任务 可能 会访问你的 key,但这不是一定会发生的行为。
所以你看到的 key 过期事件,是 “可能触发”的结果,而不是“一定会触发”的机制。
如果你需要确保 key 过期后触发回调,请使用 Redisson 的延迟队列 或 Kafka + 定时轮询 等更可靠的机制。

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

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

相关文章

OA工程自动化办公系统 – 免费Java源码

概述 功能完备的OA工程自动化办公系统Java源码&#xff0c;采用主流技术栈开发&#xff0c;无论是学习SpringBoot框架还是开发企业级应用&#xff0c;都是不可多得的优质资源。 主要内容 技术架构 ​​后端技术栈​​&#xff1a; 核心框架&#xff1a;SpringBoot 2.xORM框…

嵌入式SDK技术EasyRTC音视频实时通话助力即时通信社交/教育等多场景创新应用

一、引言​ 在数字化时代&#xff0c;即时通信已成为人们生活和工作中不可或缺的部分。音视频功能作为即时通信的核心&#xff0c;能实现更加直观、高效的信息传递。EasyRTC作为一款强大的实时通信框架&#xff0c;具备诸多优势&#xff0c;为即时通信的音视频应用提供了优质解…

BEV和OCC学习-5:数据预处理流程

参考&#xff1a;自定义数据预处理流程 — MMDetection3D 1.4.0 文档 数据预处理流程的设计 预处理流程中的各项操作主要分为数据加载、预处理、格式化、测试时的数据增强。 接下来将展示一个用于 PointPillars 模型的数据集预处理流程的例子。 train_pipeline [dict(type…

OGG 23ai for DAA 部署与补丁升级

创建ogg 用户 /usr/sbin/groupadd -g 1002 dba /usr/sbin/groupadd -g 1001 oinstall /usr/sbin/groupadd -g 1003 oper useradd -u 1001 -g oinstall -G dba,oper oracle echo "oracle" |passwd oracle --stdin创建ogg安装目录 mkdir -p /u01/app/ogg/soft mkdir …

【LangchainAgent】Agent基本构建与使用

目录 一、功能简述 代码功能概括 &#x1f3af; 核心能力 二、运作流程 三、核心代码 四、运行结果 五、代码功能拆解 ✅ 1. 环境准备与依赖导入 ✅ 2. 加载网页文档并处理为向量 ✅ 3. 创建检索工具与搜索工具 ✅ 4. 初始化语言模型与 Agent ✅ 5. 封装支持多轮记…

【云安全】以Aliyun为例聊云厂商服务常见利用手段

目录 OSS-bucket_policy_readable OSS-object_public_access OSS-bucket_object_traversal OSS-Special Bucket Policy OSS-unrestricted_file_upload OSS-object_acl_writable ECS-SSRF 云攻防场景下对云厂商服务的利用大同小异&#xff0c;下面以阿里云为例 其他如腾…

完成一个可交互的k8s管理平台的页面开发

使用deepseek完成设计一个k8s管理平台&#xff0c;关键词如下&#xff1a; 完成一个可交互的k8s管理平台的页面开发Kubernetes 管理平台页面设计 下面是一个基于现代Web技术的可交互Kubernetes管理平台的页面设计方案&#xff0c;使用React作为前端框架&#xff0c;配合Ant De…

TDengine 支持的平台汇总

TDengine 服务端支持的平台列表 注&#xff1a;1) ● 表示经过官方测试验证&#xff0c; ○ 表示非官方测试验证&#xff0c;E 表示仅企业版支持。 2) 社区版仅支持主流操作系统的较新版本&#xff0c;包括 Ubuntu 18/CentOS 7/CentOS Stream/RedHat/Debian/CoreOS/FreeBSD/Op…

使用 HTML + JavaScript 实现文章逐句高亮朗读功能

在这个信息爆炸的时代&#xff0c;我们每天都要面对大量的文字阅读。无论是学习、工作还是个人成长&#xff0c;阅读都扮演着至关重要的角色。然而&#xff0c;在快节奏的生活中&#xff0c;我们往往难以找到足够的安静时间专注于阅读。本文用 HTML JavaScript 实现了一个基于…

理解非结构化文档:将 Reducto 解析与 Elasticsearch 结合使用

作者&#xff1a;来自 Elastic Adel Wu 演示如何将 Reducto 的文档处理与 Elasticsearch 集成以实现语义搜索。 Elasticsearch 与业界领先的生成式 AI 工具和提供商有原生集成。欢迎观看我们的网络研讨会&#xff0c;了解如何超越 RAG 基础&#xff0c;或使用 Elastic 向量数据…

从Copilot到Agent,AI Coding是如何进化的?

编程原本是一项具有一定门槛的技能&#xff0c;但借助 AI Coding 产品&#xff0c;新手也能写出可运行的代码&#xff0c;非专业人员如业务分析师、产品经理&#xff0c;也能在 AI 帮助下直接生成简单应用。 这一演变对软件产业产生了深远影响。当 AI 逐步参与代码生成、调试乃…

UGUI Text/TextMeshPro字体组件

UGUI Text组件的不当使用及其性能瓶颈与优化 在Unity UGUI系统中&#xff0c;Text 组件&#xff08;或其升级版 TextMeshPro&#xff09;是显示文本信息的核心元素。然而&#xff0c;如果不当使用&#xff0c;它极易成为UI性能瓶颈的罪魁祸首&#xff0c;尤其是在预制体、属性…

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…

【个人笔记】数据库原理(西电)

写在前面&#xff1a;文中提到的页面指向&#xff08;如“p45”&#xff09;&#xff0c;除特别说明&#xff0c;都是指对应ppt上的页面&#xff0c;非同款ppt的友友可忽略 第一章 ER图和关系分解见课本p69 ER图是常用的 概念模型 方形&#xff1a;实体圆形&#xff1a;属性…

SDC命令详解:使用set_propagated_clock命令进行约束

相关阅读 SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482 目录 指定端口列表/集合 简单使用 注意事项 传播时钟是在进行了时钟树综合后&#xff0c;使用set_propagated_clock命令可以将一个理想时钟转换为传播时钟&#x…

关于华为仓颉编程语言

文章目录 一、基本概况二、技术特点1. 多范式编程2. 原生智能化3. 高性能与安全4. 全场景兼容 三、编译器与开发工具四、语言相似性对比五、行业应用实例总结 最近经常看到这个东西&#xff0c;于是搜了一下&#xff0c;整理了一些内容&#xff0c;水一篇&#xff0c;以后慢慢研…

【STM32F1标准库】理论——定时器中的输出比较

目录 一、定时器的输出比较介绍&#xff08;Output Compare&#xff09; 1.整体简介 2.输出比较单元具体功能框图 3.以PWM模式1举例 二、杂谈 1.CCR的全名 2.PWM简介 3.舵机简介 4.直流电机及驱动模块TB6612简介 一、定时器的输出比较介绍&#xff08;Output Compare…

前端开发面试题总结-HTML篇

文章目录 HTML面试高频问答一、HTML 的 src 和 href 属性有什么区别?二、什么是 HTML 语义化?三、HTML的 script 标签中 defer 和 async 有什么区别?四、HTML5 相比于 HTML有哪些更新?五、HTML行内元素有哪些? 块级元素有哪些? 空(void)元素有哪些?六、iframe有哪些优点…

Scrapy爬虫教程(新手)

1. Scrapy的核心组成 引擎&#xff08;engine&#xff09;&#xff1a;scrapy的核心&#xff0c;所有模块的衔接&#xff0c;数据流程梳理。 调度器&#xff08;scheduler&#xff09;&#xff1a;本质可以看成一个集合和队列&#xff0c;里面存放着一堆即将要发送的请求&#…

Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五模型时序预测

Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五模型时序预测 目录 Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五模型时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Transformer-BiLSTM、Transformer、CNN-BiLSTM、BiLSTM、CNN五…