Redis的键空间监听功能

文章目录

  • Redis 键空间通知
    • 一、keyspace介绍
    • 二、事件通知配置
    • 三、不同命令生成的事件
    • 四、客户端测试
    • 五、Springboot整合Redis键空间监听
      • 5.1 方式一
      • 5.2 方式二

Redis 键空间通知

一、keyspace介绍

keyspace(键空间通知)针对指定key发生的一切改动,推送给订阅的客户端,侧重于针对指定key的操作

键空间通知监听格式:__keyspace@<db>__:<key>

二、事件通知配置

默认情况下,键空间事件通知被禁用,因为虽然不太明智,但该功能会使用一些 CPU 功率。notify-keyspace-events有两种配置方式

  • 通过redis.conf配置
  • 通过config set 启用通知,重启失效
例:config set notify-keyspace-events “KEA”

将参数设置为空字符串会禁用通知。为了启用该功能,使用由多个字符组成的非空字符串,其中每个字符都有特殊含义

字符发送的通知
K键空间通知,所有通知以 __keyspace@<db>__ 为前缀
E键事件通知,所有通知以__keyevent@<db>__为前缀
gdelexpirerename 等类型无关的通用命令的通知
$string命令的通知
llist命令的通知
sset命令的通知
hhash命令的通知
zzset命令的通知
e驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
A参数 g$lshzxe 的别名

至少KE应该出现在字符串中,否则无论字符串的其余部分如何,都不会传递任何事件。

例如,要仅启用列表的键空间事件,配置参数必须设置为Kl,等等。

您可以使用该字符串KEA来启用所有类型的通知

三、不同命令生成的事件

具体的看官方文档:Redis 键空间通知,这里举几个例子:

  • DEL为每个已删除的键生成一个del事件。
  • RENAME生成两个事件,一个rename_from针对源键的事件,一个rename_to针对目标键的事件。
  • MOVE生成两个事件,一个move_from针对源键的事件,一个move_to针对目标键的事件。
  • COPY生成一个copy_to事件。
  • EXPIRE及其所有变体(PEXPIREEXPIREATPEXPIREATexpire在使用正超时(或未来时间戳)调用时都会生成一个事件。请注意,当使用过去的负超时值或时间戳调用这些命令时,键将被删除,并且仅del生成一个事件。

四、客户端测试

Redis键空间监听的本质是通过订阅与键相关的消息通知来实现的。当一个Redis键空间的事件发生时,Redis会将事件信息发送到相应的频道(channel),而订阅了该频道的客户端就会接收到这些消息通知。

1.打开redis客户端连接,然后设置所有类型事件都通知

C:\Users\Lenovo>redis-cli
127.0.0.1:6379> config set notify-keyspace-events "KEA"
OK
127.0.0.1:6379>

2.订阅一个频道,配置key为qqq:*就会触发通知

# PSUBSCRIBE命令用于订阅一个或多个符合指定模式的频道(channel),支持通配符模式
127.0.0.1:6379> PSUBSCRIBE __keyspace@*__:qqq:*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__keyspace@*__:qqq:*"
3) (integer) 1

在这里插入图片描述

3.新开一个客户端

C:\Users\Lenovo>redis-cli
127.0.0.1:6379> set qqq:111 222
OK
127.0.0.1:6379>

结果:可以看到只要qqq:*的发生了变动,就会触发通知
在这里插入图片描述

在这里插入图片描述

五、Springboot整合Redis键空间监听

5.1 方式一

1.引入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.5.4</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

2.配置redis

server.port=8080spring.redis.port=6379
spring.redis.host=127.0.0.1

3.配置监听器

@Slf4j
@Component
public class RedisListener implements MessageListener {@Overridepublic void onMessage(Message message, byte[] pattern) {System.out.println(message.toString());String body = new String(message.getBody());System.out.println(body);String channel = new String(message.getChannel());System.out.println(channel);int index = channel.indexOf(":");String key = channel.substring(index + 1); // 找到第一个冒号的位置,冒号后面就是keylog.info("redis key: {} , channel: {}", key, channel);}
}

4.开启监听以及配置监听范围

@Component
public class RedisContainer {@AutowiredRedisListener redisListener;@Autowiredprivate TaskExecutor redisListenerContainerTaskExecutor;private static final Topic TOPIC_ALL_KEYSPACE = new PatternTopic("__keyspace@*__:*");@Beanpublic RedisMessageListenerContainer container(RedisConnectionFactory factory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(factory);// __keyspace@*__:* 可以配置一个也可配置多个container.addMessageListener(redisListener, TOPIC_ALL_KEYSPACE);container.setTaskExecutor(redisListenerContainerTaskExecutor);return container;}
}

5.测试
在这里插入图片描述

5.2 方式二

1.增加redisTemplate配置

@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {// 创建RedisTemplate对象RedisTemplate<String, Object> template = new RedisTemplate<>();// 设置连接工厂template.setConnectionFactory(connectionFactory);// 创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 设置Key的序列化template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 设置Value的序列化template.setValueSerializer(jsonRedisSerializer);template.setHashValueSerializer(jsonRedisSerializer);// 返回return template;}
}

2.使用@PostConstruct,在项目启动时动态注入容器

@Slf4j
@Component
public class service {@Autowiredprivate ApplicationContext applicationContext;@Autowiredprivate TaskExecutor redisListenerContainerTaskExecutor;@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final Topic TOPIC_ALL_KEYSPACE = new PatternTopic("__keyspace@*__:*");@PostConstructvoid init(){DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();// 创建redis监听器MessageListener listener = (message, pattern) -> {System.out.println("message: " + message.toString());String body = new String(message.getBody());System.out.println("body: " + body);String channel = new String(message.getChannel());System.out.println("channel: " + channel);int index = channel.indexOf(":");String key = channel.substring(index + 1); // 找到第一个冒号的位置,冒号后面就是keylog.info("redis key: {} , channel: {}", key, channel);};// 创建redis监听适配器MessageListenerAdapter listenerAdapter = new MessageListenerAdapter(listener);// 创建redis消息监听容器RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(redisTemplate.getConnectionFactory());container.addMessageListener(listenerAdapter, TOPIC_ALL_KEYSPACE);container.setTaskExecutor(redisListenerContainerTaskExecutor);// redis消息监听容器注入到spring中BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(RedisMessageListenerContainer.class, () -> container);defaultListableBeanFactory.registerBeanDefinition("redisMessageListenerContainer", listenerBeanDefinitionBuilder.getBeanDefinition());}
}

3.结果一样
在这里插入图片描述

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

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

相关文章

Stable Diffusion AI绘画初学者指南【概述、云端环境搭建】

概述、云端环境搭建 Stable Diffusion 是什么、能干啥&#xff1f; 是一种基于深度学习的图像处理技术&#xff0c;可以生成高质量的图像。它可以在不需要真实图像的情况下&#xff0c;通过文字描述来生成逼真的图像。 可以对图像进行修复、超分辨率转换&#xff0c;将低分辨…

<Maven>项目依赖导入Maven本地仓库命令

项目工程pom.xml文件打开&#xff1a;查看报错的依赖, 将jar包放在D盘(或者其它路径都可)根目录下,在windows黑窗口执行以下命令; 举例&#xff1a;jar包名称&#xff1a; 1.api-1.0-SNAPSHOT102.jar 2.coms-cache-1.0-SNAPSHOT.jar 命令&#xff1a; mvn install:install-fi…

Scratch 游戏传统导路算法

1 深度优先算法&#xff08;DFS&#xff09; 这个算法不是最短路算法&#xff0c;只是一个基本的搜索算法&#xff0c;但是可以得出图中是否能找到指定节点 大致的思路&#xff1a; 从起始节点开始&#xff0c;将其标记为已访问。 检查当前节点的相邻节点中是否存在未访问的节…

【计算机网络】传输层协议 -- TCP协议

文章目录 1. TCP协议的引入2. TCP协议的特点3. TCP协议格式3.1 序号与确认序号3.2 发送缓冲区与接收缓冲区3.3 窗口大小3.4 六个标志位 4. 确认应答机制5. 超时重传机制6. 连接管理机制6.1 三次握手6.2 四次挥手 7. 流量控制8. 滑动窗口9. 拥塞控制10. 延迟应答11. 捎带应答12.…

【Spring】Spring之依赖注入源码解析

1 Spring注入方式 1.1 手动注入 xml中定义Bean&#xff0c;程序员手动给某个属性赋值。 set方式注入 <bean name"userService" class"com.firechou.service.UserService"><property name"orderService" ref"orderService"…

数据库访问中间件--springdata-jpa的基本使用

二、单表SQL操作-使用关键字拼凑方法 回顾 public interface UserRepository extends JpaRepository<User,Integer> {User findByUsernameLike(String username); }GetMapping("/user/username/{username}")public Object findUserByUsername(PathVariable S…

【CSS】视频文字特效

效果展示 index.html <!DOCTYPE html> <html><head><title> Document </title><link type"text/css" rel"styleSheet" href"index.css" /></head><body><div class"container"&g…

三星书画联展:三位艺术家开启国风艺术之旅

7月22日&#xff0c;由广州白云区文联、白云区工商联主办的“三星书画联展”&#xff0c;在源美术馆正式开展。本次书画展展出的艺术种类丰富&#xff0c;油画、国画、彩墨画、书法等作品异彩纷呈。广东省政协原副主席、农工党省委书画院名誉院长马光瑜&#xff0c;意大利艺术研…

哈工大计算机网络课程局域网详解之:交换机概念

哈工大计算机网络课程局域网详解之&#xff1a;交换机概念 文章目录 哈工大计算机网络课程局域网详解之&#xff1a;交换机概念以太网交换机&#xff08;switch&#xff09;交换机&#xff1a;多端口间同时传输交换机转发表&#xff1a;交换表交换机&#xff1a;自学习交换机互…

iPhone 7透明屏的显示效果怎么样?

iPhone 7是苹果公司于2016年推出的一款智能手机&#xff0c;它采用了4.7英寸的Retina HD显示屏&#xff0c;分辨率为1334x750像素。 虽然iPhone 7的屏幕并不是透明的&#xff0c;但是苹果公司在设计上采用了一些技术&#xff0c;使得用户在使用iPhone 7时可以有一种透明的感觉…

Android 热修复

Android 热修复 本文链接&#xff1a;https://blog.csdn.net/feather_wch/article/details/132052856 文章目录 Android 热修复方案对比AndFixDeprecateRobust-即时生效Tinker-非及时生效 ClassLoader实战一手动打补丁包 热修复二 方案对比 AndFixDeprecate 1、AndFix为什么…

【STM32零基础入门教程03】GPIO输入输出之GPIO框图分析

本章节主要讲解点亮LED的基本原理&#xff0c;以及GPIO框图的讲解。 如何点亮LED&#xff08;输出&#xff09; 首先我们查看原理图&#xff0c;观察电路图中LED的连接情况&#xff0c;如下图可以看出我们的板子中LED一端通过限流电阻连接的PB0另一端连接的是高电平VCC&#xf…

排序进行曲-v2.0

小程一言 这篇文章是在排序进行曲1.0之后的续讲&#xff0c; 0之后的续讲,英语在上一篇讲的排序的基本概念与分类0之后的续讲, 英语在上一篇讲的排序的基本概念与分类这片主要是对0之后的续讲,英语在上一篇讲的排序的基本概念与分类这 篇主要是对几个简单的排序进行细致的分析…

JavaData:JDK8之前传统的日期和时间

Data JDK8之前传统的日期和时间 //目标:掌握Date日期类的使用。 //1、创建一个Date的对象:代表系统当前时间信息的。 Date d new Date(); system.out.println(d);//2、拿到时间毫秒值。 long time d.getTime(); system.out.println(time);//3、把时间毫秒值转换成日期对象:2…

企业电子招投标采购系统源码之首页设计

&#xfeff;功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&…

Unity-缓存池

一、.基础缓存池实现 继承的Singleton脚本为 public class Singleton<T> where T : new() {private static T _instance;public static T GetIstance(){if (_instance null)_instance new T();return _instance;} } 1.PoolManager using System.Collections; using S…

Pytest-BDD 行为驱动开发测试

文章目录 01 BDD02 pytest-BDD03 安装pytest-BDD04 pytest-bdd的框架结构05 pytest-bdd基础使用5.1 第一步:添加需求描述/用户场景5.1.1 BDD的表达语法5.1.2 创建`.feature`文件5.2 第二步:实现用户场景5.2.1 用户场景的解析/实现5.2.2 使用`scenarios`或`@scenario`关联用户…

python 测试磁盘读写速度和内存读写速度.

import time import os # from SpeedTest import perform_default_speedtest# 测试硬盘读写速度 def test_disk_speed():filename "./testfile.bin"# 生成一个1GB大小的测试文件with open(filename, "wb") as f:f.write(os.urandom(1024*1024*1024))# 从…

C语言手撕单链表

一、链表的概念 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;也就是内存存储不是像顺序表那么连续存储&#xff0c;而是以结点的形式一块一块存储在堆上的&#xff08;用动态内存开辟&#xff09;。 既然在内存上不是连续存储&#xff0c;那我们如何将这一…

Qt/C++音视频开发50-不同ffmpeg版本之间的差异处理

一、前言 ffmpeg的版本众多&#xff0c;从2010年开始计算的项目的话&#xff0c;基本上还在使用的有ffmpeg2/3/4/5/6&#xff0c;最近几年版本彪的比较厉害&#xff0c;直接4/5/6&#xff0c;大版本之间接口有一些变化&#xff0c;特别是一些废弃接口被彻底删除了&#xff0c;…