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视频解码与渲染。 今…...

【Matlab】连接SQL Server 全过程
文章目录 一、下载与安装1.1 SQL Server1.2 SSMS1.3 OLE DB 驱动程序 二、数据库配置2.1 SSMS2.2 SQL Server里面设置2.3 设置防火墙2.4 设置ODBC数据源 三、matlab 链接测试 一、下载与安装 微软的,所以直接去微软官方下载即可。 1.1 SQL Server 下载最免费的Ex…...
元图CAD:一键解锁PDF转CAD,OCR技术赋能高效转换
在建筑、工程与制造领域,图纸的精准性与高效协作是项目成功的关键。然而,传统PDF文件中的文字和图形往往难以直接编辑,手动输入不仅耗时易错,还可能因格式问题导致信息丢失。元图CAD凭借创新的OCR文字识别技术,重新定义…...
针对“仅某个地区出现Bug”的原因分析与解决方案
一、核心排查方向(按优先级排序) 地区相关配置差异 检查点: 该地区是否有独立的配置文件或数据库分片?是否启用了地区特定的功能开关(Feature Flag)或AB测试?本地化内容(如语言、时…...
ROS2,工作空间中新建了一个python脚本,需要之后作为节点运行。告诉我步骤?
提问 ROS2,工作空间中新建了一个python脚本,需要之后运行。告诉我步骤? 大概要包括而不限于:chmod给可执行权限、setup.py中entry point的配置,如果在launch文件中要使用,还涉及到launch.py文件的配置。最…...

Cursor + Claude 4:微信小程序流量主变现开发实战案例
前言 随着微信小程序生态的日益成熟,越来越多的开发者开始关注如何通过小程序实现流量变现。本文将详细介绍如何使用Cursor编辑器结合Claude 4 AI助手,快速开发一个具备流量主变现功能的微信小程序,并分享实际的开发经验和变现策略。 项目…...
C++ 中的 const 知识点详解,c++和c语言区别
目录 一。C 中的 const 知识点详解1. 基本用法1.1) 定义常量1.2) 指针与 const 2. 函数中的 const2.1)const 参数2.2)const 成员函数 3. 类中的 const3.1)const 成员变量3.2)const 对象 4. const 返回值5. …...

作为过来人,浅谈一下高考、考研、读博
写在前面 由于本人正在读博,标题中的三个阶段都经历过或正在经历,本意是闲聊,也算是给将要经历的读者们做个参考、排雷。本文写于2022年,时效性略有落后,不过逻辑上还是值得大家参考,若所述存在偏颇&#…...
RabbitMQ 在解决数据库高并发问题中的定位和核心机制
RabbitMQ 在解决数据库高并发问题中的定位和核心机制 它是间接但极其有效的解决方案,以下内容聚焦如何最大化发挥 RabbitMQ 的潜力: 一、核心机制落地强化方案 1. 精准的异步化切割 关键原则:区分 “必须同步” 和 “可异步” 操作 #merma…...

Microsoft前后端不分离编程新风向:cshtml
文章目录 什么是CSHTML?基础语法内联表达式代码块控制结构 布局页面_ViewStart.cshtml_Layout.cshtml使用布局 模型绑定强类型视图模型集合 HTML辅助方法基本表单验证 局部视图创建局部视图使用局部视图 高级特性视图组件依赖注入Tag Helpers 性能优化缓存捆绑和压缩…...

selinux firewalld
一、selinux 1.说明 SELinux 是 Security-Enhanced Linux 的缩写,意思是安全强化的 linux; SELinux 主要由美国国家安全局(NSA)开发,当初开发的目的是为了避免资源的误用 DAC(Discretionary Access Cont…...