当前位置: 首页 > news >正文

Spring Boot集成Redis实现keyspace监听 | Spring Cloud 34

一、前言

在前面我们通过以下章节对Rediskeyevent键事件通知)使用有了基础的了解:

Spring Boot集成Redis实现keyevent监听 | Spring Cloud 33

现在开始我们正式学习Rediskeyspace键空间通知),在本章节主要进行对以下部分讲解说明:

  • 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>__ 为前缀
gdelexpirerename 等类型无关的通用命令的通知
$string命令的通知
llist命令的通知
sset命令的通知
hhash命令的通知
zzset命令的通知
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 secondsEXPIREAT 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 incrementDECRBY 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 destinationBRPOPLPUSH source destination timeout 产生一个 rpop 通知,以及一个 lpush 通知。两个命令都会保证 rpop 的通知在 lpush 的通知之前分发。如果从键弹出元素之后,被弹出的列表键被清空,那么还会产生一个 del 通知。

  • HSET hash field valueHSETNX hash field valueHMSET 都只产生一个 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 …] 分别产生 sinterstoresunionostoresdiffstore 三种通知。如果用于保存结果的键已经存在,那么还会产生一个 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] 分别产生 zinterstorezunionstore 两种通知。如果用于保存结果的键已经存在,那么还会产生一个 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,每次消费都会创建一个线程来处理,这样就会有大量的新线程被创建。生产环境下建议使用自定义线程池,减少性能损耗。

http://www.lryc.cn/news/58458.html

相关文章:

  • 如何搭建chatGPT4.0模型-国内如何用chatGPT4.0
  • 【故障定位】基于多元宇宙算法的主动配电网故障定位方法研究(Matlab代码实现)
  • 基于html+css的自适应展示1
  • DolphinDB +Python Airflow 高效实现数据清洗
  • pip3 升级软件包时遇到超时错误解决方法
  • Linux环境开机自启动
  • 字节8年测试经验,送给想要学习自动化测试的同学6条建议
  • 快速搭建springboot websocket客户端
  • Python 操作 MongoDB 详解
  • 虹科案例 | 丝芙兰xDomo:全球美妆巨头商业智能新玩法
  • 10种优雅的MyBatis写法,同事用了都说好
  • SQL删除记录方式汇总
  • 用in函数嵌入子查询作为条件时查出结果为空
  • 电商行业如何利用飞项解决跨部门协作难题
  • 全网最详细,Jmeter性能测试-性能基础详解,参数化函数取值(二)
  • 选择排序的简单理解
  • 使用js封装一个循环链表
  • NumPy 秘籍中文第二版:二、高级索引和数组概念
  • 新品-图灵超频工作站GT430M介绍
  • js时间格式化精确到毫秒
  • QT样式表详解
  • 最值得入手的好物有哪些,推荐几款实用的数码好物
  • 【20230407】NVIDIA显卡算力、Jetson比较
  • dsl语法
  • 不让CPU偷懒
  • 动力节点王鹤SpringBoot3笔记——第七章 视图技术Thymeleaf
  • 从比特保存和信息保存看数字资源长期保存
  • 兰伯特光照模型(Lambert Lighting)和半兰伯特光照模型(Half-Lanbert)
  • Python 进阶指南(编程轻松进阶):二、环境配置和命令行
  • 求职半年,三月成功拿到阿里offer,分享一波面经...