Spring Boot集成Redis实现keyspace监听 | Spring Cloud 34
一、前言
在前面我们通过以下章节对Redis的keyevent(键事件通知)使用有了基础的了解:
Spring Boot集成Redis实现keyevent监听 | Spring Cloud 33
现在开始我们正式学习Redis的keyspace(键空间通知),在本章节主要进行对以下部分讲解说明:
keyspace(键空间通知)介绍Redis事件通知开启方式及配置说明keyspace各种事件通知的产生keyspace监听的redis-cli客户端验证Spring Boot集成Redis实现keyspace监听RedisMessageListenerContainer使用自定义线程池
二、Redis事件通知
2.1 keyspace介绍
keyspace(键空间通知)针对指定key发生的一切改动,推送给订阅的客户端,侧重于针对指定key的操作
键空间通知监听格式:
__keyspace@<db>__:<key>
2.2 Redis事件通知配置
因为Redis事件通知功能需要消耗一定的资源,默认情况下该功能的关闭的。
-
使用
config set命令来临时开启或关闭键空间通知功能(此方式Redis重启将会被还原) -
通过修改
redis.conf配置,永久开启此功能
notify-keyspace-events可以是以下任意组合:
| 字符 | 发送的通知 |
|---|---|
| K | 键空间通知,所有通知以 __keyspace@<db>__ 为前缀 |
| E | 键事件通知,所有通知以 __keyevent@<db>__ 为前缀 |
| g | del、expire、rename 等类型无关的通用命令的通知 |
| $ | string命令的通知 |
| l | list命令的通知 |
| s | set命令的通知 |
| h | hash命令的通知 |
| z | zset命令的通知 |
| x | 过期事件:每当有过期键被删除时发送 |
| e | 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送 |
| A | 参数 g$lshzxe 的别名 |
注意:参数至少要有一个
K或者E,否则不会有任何通知,将参数设为KEA表示所有类型的通知
2.3 keyspace各种事件通知的产生
-
DEL key [key …]命令为每个被删除的键产生一个del通知。 -
RENAME key newkey产生两个通知:为来源键(source key)产生一个rename_from通知,并为目标键(destination key)产生一个rename_to通知。 -
EXPIRE key seconds和EXPIREAT key timestamp在键被正确设置过期时间时产生一个expire通知。当EXPIREAT key timestamp设置的时间已经过期,或者EXPIRE key seconds传入的时间为负数值时,键被删除,并产生一个del通知。 -
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA] [STORE destination]在命令带有STORE参数时产生一个sortstore事件。如果STORE指示的用于保存排序结果的键已经存在,那么程序还会发送一个del事件。 -
SET key value [EX seconds] [PX milliseconds] [NX|XX]以及它的所有变种(SETEX key seconds value 、 SETNX key value 和 GETSET key value)都产生set通知。其中SETEX key seconds value还会产生expire通知。 -
MSET key value [key value …]为每个键产生一个set通知。 -
SETRANGE key offset value产生一个setrange通知。 -
INCR key 、 DECR key 、 INCRBY key increment和DECRBY key decrement都产生incrby通知。 -
INCRBYFLOAT key increment产生incrbyfloat通知。 -
APPEND key value产生append通知。 -
LPUSH key value [value …]和LPUSHX key value都产生单个lpush通知,即使有多个输入元素时,也是如此。 -
RPUSH key value [value …]和RPUSHX key value都产生单个rpush通知,即使有多个输入元素时,也是如此。 -
RPOP key产生rpop通知。如果被弹出的元素是列表的最后一个元素,那么还会产生一个del通知。 -
LPOP key产生lpop通知。如果被弹出的元素是列表的最后一个元素,那么还会产生一个del通知。 -
LINSERT key BEFORE|AFTER pivot value产生一个linsert通知。 -
LSET key index value产生一个 lset通知。 -
LTRIM key start stop产生一个ltrim通知。如果LTRIM key start stop执行之后,列表键被清空,那么还会产生一个del通知。 -
RPOPLPUSH source destination和BRPOPLPUSH source destination timeout产生一个rpop通知,以及一个lpush通知。两个命令都会保证rpop的通知在lpush的通知之前分发。如果从键弹出元素之后,被弹出的列表键被清空,那么还会产生一个del通知。 -
HSET hash field value、HSETNX hash field value和HMSET都只产生一个hset通知。 -
HINCRBY产生一个hincrby通知。 -
HINCRBYFLOAT产生一个hincrbyfloat通知。 -
HDEL产生一个hdel通知。如果执行HDEL之后,哈希键被清空,那么还会产生一个del通知。 -
SADD key member [member …]产生一个sadd通知,即使有多个输入元素时,也是如此。 -
SREM key member [member …]产生一个srem通知,如果执行SREM key member [member …]之后,集合键被清空,那么还会产生一个del通知。 -
SMOVE source destination member为来源键(source key)产生一个srem通知,并为目标键(destination key)产生一个sadd事件。 -
SPOP key产生一个spop事件。如果执行SPOP key之后,集合键被清空,那么还会产生一个del通知。 -
SINTERSTORE destination key [key …]、SUNIONSTORE destination key [key …]和
SDIFFSTORE destination key [key …]分别产生sinterstore、sunionostore和sdiffstore三种通知。如果用于保存结果的键已经存在,那么还会产生一个del通知。 -
ZINCRBY key increment member产生一个zincr通知。(译注:非对称,请注意。) -
ZADD key score member [[score member] [score member] …]产生一个zadd通知,即使有多个输入元素时,也是如此。 -
ZREM key member [member …]产生一个zrem通知,即使有多个输入元素时,也是如此。如果执行ZREM key member [member …]之后,有序集合键被清空,那么还会产生一个del通知。 -
ZREMRANGEBYSCORE key min max产生一个zrembyscore通知。(译注:非对称,请注意。)如果用于保存结果的键已经存在,那么还会产生一个del通知。 -
ZREMRANGEBYRANK key start stop产生一个zrembyrank通知。(译注:非对称,请注意。)如果用于保存结果的键已经存在,那么还会产生一个del通知。 -
ZINTERSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]和ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]分别产生zinterstore和zunionstore两种通知。如果用于保存结果的键已经存在,那么还会产生一个del通知。
三、客户端验证
此客户端验证只针对
keyspace(键空间通知)
3.1 运行redis客户端
redis-cli
3.2 开启监听
PSUBSCRIBE __keyspace@*__:*
注意:因模糊匹配使用
psubscribe命令
3.3 执行SETEX操作
新开启一个
redis客户端
SETEX mykey 10 redis
SETEX为指定的key设置值及其过期时间。如果key已经存在,SETEX命令将会替换旧的值。

3.4 查看监听
切换至开启监听的
redis客户端

- 发生
set事件 - 发生
expire事件 - 发生
expired时间
四、集成Redis实现keyspace监听
4.1 实现原理
请见 Spring Boot集成Redis实现keyevent监听 | Spring Cloud 33 文章 4.1 部分。
4.2 实现MessageListener监听器方式
4.2.1 自定义监听器RedisListener
com/gm/key/listen/listener/RedisListener.java:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class RedisListener implements MessageListener {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Overridepublic void onMessage(Message message, byte[] pattern) {String key = message.toString();RedisSerializer<?> serializer = redisTemplate.getValueSerializer();String channel = String.valueOf(serializer.deserialize(message.getChannel()));log.info("redis key: {} , channel: {}", key, channel);}
}
4.2.2 开启监听及监听范围及事件类型
com/gm/key/listen/config/RedisListenerConfig.java:
package com.gm.key.listen.config;import com.gm.key.listen.listener.RedisListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;@Configuration
public class RedisListenerConfig {@AutowiredRedisListener redisListener;private static final Topic TOPIC_ALL_KEYSPACE = new PatternTopic("__keyspace@*__:*");@Beanpublic ThreadPoolTaskExecutor redisListenerTaskExecutor() {ThreadPoolTaskExecutor springSessionRedisTaskExecutor = new ThreadPoolTaskExecutor();springSessionRedisTaskExecutor.setCorePoolSize(12);springSessionRedisTaskExecutor.setMaxPoolSize(36);springSessionRedisTaskExecutor.setKeepAliveSeconds(60);springSessionRedisTaskExecutor.setThreadNamePrefix("redis-listener-");return springSessionRedisTaskExecutor;}@Beanpublic RedisMessageListenerContainer container(RedisConnectionFactory factory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(factory);container.addMessageListener(redisListener, TOPIC_ALL_KEYSPACE);container.setTaskExecutor(redisListenerTaskExecutor());return container;}
}
请提前确认
Redis服务端已开启keyspace(键空间通知)
RedisMessageListenerContainer的默认使用线程池是SimpleAsyncTaskExecutor,每次消费都会创建一个线程来处理,这样就会有大量的新线程被创建。生产环境下建议使用自定义线程池,减少性能损耗。
相关文章:
Spring Boot集成Redis实现keyspace监听 | Spring Cloud 34
一、前言 在前面我们通过以下章节对Redis的keyevent(键事件通知)使用有了基础的了解: Spring Boot集成Redis实现keyevent监听 | Spring Cloud 33 现在开始我们正式学习Redis的keyspace(键空间通知),在本…...
如何搭建chatGPT4.0模型-国内如何用chatGPT4.0
国内如何用chatGPT4.0 在国内,目前可以通过以下途径使用 OpenAI 的 ChatGPT 4.0: 自己搭建模型:如果您具备一定的技术能力,可以通过下载预训练模型和相关的开发工具包,自行搭建 ChatGPT 4.0 模型。OpenAI提供了相关的…...
【故障定位】基于多元宇宙算法的主动配电网故障定位方法研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
基于html+css的自适应展示1
准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…...
DolphinDB +Python Airflow 高效实现数据清洗
DolphinDB 作为一款高性能时序数据库,其在实际生产环境中常有数据的清洗、装换以及加载等需求,而对于该如何结构化管理好 ETL 作业,Airflow 提供了一种很好的思路。本篇教程为生产环境中 ETL 实践需求提供了一个解决方案,将 Pytho…...
pip3 升级软件包时遇到超时错误解决方法
如果你在使用 pip3 升级软件包时遇到超时错误,可能是因为下载速度缓慢或网络不稳定。以下是解决方法: 更改 pip3 源:你可以切换到其他 pip3 源,例如清华、阿里等等,以提高下载速度。 pip3 install -i https://pypi.tun…...
Linux环境开机自启动
1.制作服务 在/etc/systemd/system/路径下创建kkFile.service文件 cd /etc/systemd/system/ vim kkFile.service2.写入如下内容 [Unit] DescriptionkkFile service [Service] Typeforking ExecStart/sinosoft/yjya/kkFileView-4.0.0/bin/startup.sh [Install] WantedBymulti…...
字节8年测试经验,送给想要学习自动化测试的同学6条建议
我的职业生涯开始和大多数测试人一样,开始接触都是纯功能界面测试。那时候在一家电商公司做测试,做了有一段时间,熟悉产品的业务流程以及熟练测试工作流程规范之后,效率提高了,工作比较轻松,也得到了更好的…...
快速搭建springboot websocket客户端
一、前言WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽&…...
Python 操作 MongoDB 详解
嗨害大家好鸭!我是芝士❤ 一、前言 MongoDB属于 NoSQL(非关系型数据库), 是一个基于分布式文件存储的开源数据库系统。 二、操作 MongoDB 1. 安装 pymongo python 使用第三方库来连接操作 MongoDB, 所以我们首先安…...
虹科案例 | 丝芙兰xDomo:全球美妆巨头商业智能新玩法
全球美妆行业的佼佼者丝芙兰,其走向成功绝非仅依靠品牌知名度和营销手段。身为数据驱动型企业,2018年以来,丝芙兰就率先在行业内采用虹科提供的Domo商业智能进行数据分析和决策,并首先享受了运营优化、效率提升所带来的商业价值。…...
10种优雅的MyBatis写法,同事用了都说好
用来循环容器的标签forEach,查看例子 foreach元素的属性主要有item,index,collection,open,separator,close。 item:集合中元素迭代时的别名, index:集合中元素迭代时的索引 open…...
SQL删除记录方式汇总
大家好,我是RecordLiu! 今天给大家分享的是SQL中删除记录的不同方式,我会用几道真题来给大家讲解。 题目直达链接: 牛客网在线SQL编程练习 切换到SQL篇就能看到了。 我这里先列下知识点: SQL中进行简单删除的语法是什么?SQL…...
用in函数嵌入子查询作为条件时查出结果为空
用in函数嵌入子查询作为条件时查出结果为空 问题: SELECT * FROM SGGCDB_VIEW sv WHERE RES_ID IN (SELECT urrv.RES_ID FROM IBPS_ERP.USER_ROLE_RES_VIEW urrv WHERE urrv.ID_ 1069978138403930112 )结果未空值。 原因: 首先,SELECT u…...
电商行业如何利用飞项解决跨部门协作难题
在电商行业中,跨部门合作是最常见的事。从产品方案到设计方案,从市场定价到销售策略,从采购需求到成本清单……在电商新品研发到正式售卖的过程中,存在着大量跨部门协作与逆向流程,但任务零碎、沟通难、进度难同步、文…...
全网最详细,Jmeter性能测试-性能基础详解,参数化函数取值(二)
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 参数化详解 Jmeter中…...
选择排序的简单理解
详细描述 选择排序的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾…...
使用js封装一个循环链表
直接不说废话,直接上代码,这里继承了单向链表的类LinkList ,可以查看之前的文章,点这里 class Node {constructor(element) {this.element element;this.next null;} }class CirularLinkedList extends LinkList {constructor(…...
NumPy 秘籍中文第二版:二、高级索引和数组概念
原文:NumPy Cookbook - Second Edition 协议:CC BY-NC-SA 4.0 译者:飞龙 在本章中,我们将介绍以下秘籍: 安装 SciPy安装 PIL调整图像大小比较视图和副本翻转 Lena花式索引位置列表索引布尔值索引数独的步幅技巧广播数…...
新品-图灵超频工作站GT430M介绍
曾经历史 UltraLAB GTxxxM系列是西安坤隆公司专注于超频高速计算应用的图形工作站。 2008年 获取排名第一、二的中国象棋软件均采用该机型。 2019年 推出采用Intel 超频Xeon(28核4.8GHz)显著提升电磁仿真频域算法求解、第一个解决8K视频解码与渲染。 今…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...
