Redis 过期了解

news2025/6/7 8:58:39

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 的 key
            if (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.coloradmin.cn/o/2402697.html

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

相关文章

JAVA理论-JAVA基础知识

1.Java 基础 知识 1.1 面向对象的特征&#xff08;了解&#xff09; 面向对象的特征&#xff1a;封装、继承、多态、抽象 封装&#xff1a;就是把对象的属性和行为&#xff08;数据&#xff09;结合为一个独立的整体&#xff0c;并尽量隐藏对象的内部细节&#xff0c;公开我希…

免费无限使用GPT Plus、Claude Pro、Grok Super、Deepseek满血版

渗透智能-ShirtAI&#xff0c;可以免费无限使用GPT Plus、Claude Pro、Grok Super、Deepseek满血版、除此之外还能免费使用AI搜索、Gemini AI、AI照片修复、AI橡皮擦、AI去背景、AI智能抠图、AI证件照、OCR识别、在线思维导图、在线绘图工具、PDF工具箱、PDF翻译。 传送入口&a…

SoloSpeech - 高质量语音处理模型,一键提取指定说话人音频并提升提取音频清晰度和质量 本地一键整合包下载

视频教程&#xff1a; 一个强大的语音分离和降噪软件 SoloSpeech 是由约翰霍普金斯大学、香港中文大学、南洋理工大学、清华大学及布拉格理工大学等多所高校共同主导开源的一个创新的语音处理项目&#xff0c;旨在解决在多人同时说话的环境中&#xff0c;准确提取并清晰呈现特定…

深入解析 Java ClassLoader:揭开 JVM 动态加载的神秘面纱

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; Java 之所以能实现“一次编写&#xff0c;到处运行”&#xff0c;很大程度得益于其虚拟机&#xff08;JVM&#xff09;强大的跨平台能力。…

CICD实战(一) -----Jenkins的下载与安装

服务器IPJenkins192.168.242.153gitlab192.168.242.154 1、安装工具&#xff08;可选&#xff0c;如果有就不需要安装&#xff09; sudo yum install wget net-tools 2、关闭防火墙 #关闭防火墙(如果是云服务器部署,去安全组放通对应的端口即可) systemctl stop firewalld …

Devops系列---python基础篇二

1、列表 1.1 概念 格式&#xff1a; 名称 [ “元素1”,“元素2”,…] #定义一个列表 computer ["主机","键盘","显示器","鼠标"]类型方法用途查index(“元素”)查看元素索引位置count(“元素”)统计元素出现的次数reverse()倒序排…

​​TLV4062-Q1​​、TLV4082-Q1​​迟滞电压比较器应用笔记

文章目录 主要作用应用场景关键优势典型应用示意图TLV4062-Q1 和 TLV4082-Q1 的主要作用及应用场景如下: 主要作用 精密电压监测:是一款双通道、低功耗比较器,用于监测输入电压是否超过预设阈值。 集成高精度基准电压源(阈值精度1%),内置60mV迟滞功能,可避免因噪声导致的…

DHCP介绍

DHCP介绍 1 DHCP简述2 DHCP协议分析2.1 主要流程2.2 DHCP全部报文介绍2.3 IP租用更新报文2.4 DHCP协议抓包分析 3 DHCP应用3.1 DNSmasq参数配置3.2 DNSmasq框架代码3.2.1 创建socket监听67端口3.2.2 监听67端口3.2.3 处理DHCP请求 3.3 DNSmasq模块排障方法 4 常见问题排查4.1 问…

[蓝桥杯]耐摔指数

耐摔指数 题目描述 X 星球的居民脾气不太好&#xff0c;但好在他们生气的时候唯一的异常举动是&#xff1a;摔手机。 各大厂商也就纷纷推出各种耐摔型手机。X 星球的质监局规定了手机必须经过耐摔测试&#xff0c;并且评定出一个耐摔指数来&#xff0c;之后才允许上市流通。…

2024年第十五届蓝桥杯青少Scratch初级组-国赛—画矩形

2024年第十五届蓝桥杯青少Scratch初级组-国赛—画矩形 题目点下方&#xff0c;支持在线编程&#xff0c;在线获取源码和素材&#xff5e; 画矩形_scratch_少儿编程题库学习中心-嗨信奥 程序演示可点下方&#xff0c;支持源码获取&#xff5e; 画矩形-scratch作品-少儿编程题库…

JMM初学

文章目录 1,线程间的同步和通信1.1, 共享内存并发模型 (Shared Memory Model)线程通信机制线程同步机制特点 1.2, 消息传递并发模型 (Message Passing Model)线程通信机制线程同步机制特点 适用场景对比 2,Java内存模型JMM2.0,Java内存模型的基础&#xff08;1&#xff09;内存…

构建云原生安全治理体系:挑战、策略与实践路径

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;从传统安全走向“云原生安全” 随着企业 IT 架构从传统单体系统向容器化、微服务和云原生平台转型&#xf…

vcs仿真产生fsdb波形的两种方式

目录 方法一&#xff1a; 使用verilog自带的系统函数 方法二&#xff1a; 使用UCLI command 2.1 需要了解什么是vcs的ucli&#xff0c;怎么使用ucli&#xff1f; 2.2 使用ucli dump波形的方法 使用vcs仿真产生fsdb波形有两种方式&#xff0c;本文参考《vcs user guide 20…

Go语言底层(三): sync 锁 与 对象池

1. 背景 在并发编程中&#xff0c;正确地管理共享资源是构建高性能程序的关键。Go 语言标准库中的 sync 包提供了一组基础而强大的并发原语&#xff0c;用于实现安全的协程间同步与资源控制。本文将简要介绍 sync 包中常用的类型和方法: sync 锁 与 对象池&#xff0c;帮助开发…

2025年06月06日Github流行趋势

项目名称&#xff1a;agent-zero 项目地址url&#xff1a;https://github.com/frdel/agent-zero项目语言&#xff1a;Python历史star数&#xff1a;8958今日star数&#xff1a;324项目维护者&#xff1a;frdel, 3clyp50, linuztx, evrardt, Jbollenbacher项目简介&#xff1a;A…

动态规划 熟悉30题 ---上

本来是要写那个二维动态规划嘛&#xff0c;但是我今天在问题时候&#xff0c;一个大佬就把他初一时候教练让他练dp的30题发出来了&#xff08;初一&#xff0c;啊虽然知道计算机这一专业&#xff0c;很多人从小就学了&#xff0c;但是我每次看到一些大佬从小学还是会很羡慕吧或…

Linux系统:ELF文件的定义与加载以及动静态链接

本节重点 ELF文件的概念与结构可执行文件&#xff0c;目标文件ELF格式的区别ELF文件的形成过程ELF文件的加载动态链接与静态链接动态库的编址与方法调用 一、ELF文件的概念与结构 1.1 文件概述 ELF&#xff08;Executable and Linkable Format&#xff09;即“可执行与可链…

【国产化适配】如何选择高效合规的安全数据交换系统?

一、安全数据交换系统的核心价值与国产化需求 在数字化转型浪潮中&#xff0c;企业数据流动的频率与规模呈指数级增长&#xff0c;跨网文件传输已成为日常运营的刚需&#xff0c;所以安全数据交换系统也是企业必备的工具。然而&#xff0c;数据泄露事件频发、行业合规要求趋严…

简化复杂系统的优雅之道:深入解析 Java 外观模式

一、外观模式的本质与核心价值 在软件开发的世界里&#xff0c;我们经常会遇到这样的场景&#xff1a;一个复杂的子系统由多个相互协作的类组成&#xff0c;这些类之间可能存在错综复杂的依赖关系和交互逻辑。当外部客户端需要使用这个子系统时&#xff0c;往往需要了解多个类…

设计模式杂谈-模板设计模式

在进入正题之前&#xff0c;先引入这样一个场景&#xff1a; 程序员A现在接到这样一个需求&#xff1a;这个需求有10个接口&#xff0c;这些接口都需要接收前端的传参&#xff0c;以及给前端返回业务状态信息。出于数据保密的要求&#xff0c;不管是前端传参还是最终参数返回都…