SpringBoot监听redis Key变化事件详解
键空间通知(keyspace notification)
一 、功能概览
键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种方式改动了 Redis key变化的事件。
所有修改key键的命令。
所有接收到 LPUSH key value [value …] 命令的键。
db数据库中所有已过期的键。
事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发, 因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下, 直接使用键空间通知功能。
因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果你的程序需要可靠事件通知(reliable notification of events), 那么目前的键空间通知可能并不适合你: 当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件。
未来将会支持更可靠的事件分发, 这种支持可能会通过让订阅与发布功能本身变得更可靠来实现, 也可能会在 Lua 脚本中对消息(message)的订阅与发布进行监听, 从而实现类似将事件推入到列表这样的操作。
二、事件类型
对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件。
比如说,对0
号数据库的键mykey
执行DEL key [key …]
命令时, 系统将分发两条消息, 相当于执行以下两个PUBLISH channel message
命令:
PUBLISH __keyspace@0__:mykey del
PUBLISH __keyevent@0__:del mykey
订阅第一个频道 __keyspace@0__:mykey 可以接收 0 号数据库中所有修改键 mykey 的事件, 而订阅第二个频道 __keyevent@0__:del则可以接收 0 号数据库中所有执行 del 命令的键。
以 keyspace 为前缀的频道被称为键空间通知(key-space notification), 而以 keyevent 为前缀的频道则被称为键事件通知(key-event notification)。
当 del mykey 命令执行时:
键空间频道的订阅者将接收到被执行的事件的名字,在这个例子中,就是 del 。
键事件频道的订阅者将接收到被执行事件的键的名字,在这个例子中,就是 mykey 。
三、配置
因为开启键空间通知功能需要消耗一些 CPU , 所以在默认配置下, 该功能处于关闭状态。
可以通过修改 redis.conf 文件, 或者直接使用 CONFIG SET 命令来开启或关闭键空间通知功能:
当 notify-keyspace-events 选项的参数为空字符串时,功能关闭。
另一方面,当参数不是空字符串时,功能开启。
notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:
输入的参数中至少要有一个K
或者E
, 否则的话, 不管其余的参数是什么, 都不会有任何通知被分发。
举个例子, 如果只想订阅键空间中和列表相关的通知, 那么参数就应该设为Kl
, 诸如此类。
将参数设为字符串"AKE"
表示发送所有类型的通知。
每当一个键因为过期而被删除时,产生一个
expired
通知。每当一个键因为
maxmemory
政策而被删除以回收内存时,产生一个evicted
通知。
所有命令都只在键真的被改动了之后,才会产生通知。
比如说,当SREM key member [member …]
试图删除不存在于集合的元素时,删除操作会执行失败,因为没有真正的改动键,所以这一操作不会发送通知。
如果对命令所产生的通知有疑问, 最好还是使用以下命令, 自己来验证一下:
Redis 使用以下两种方式删除过期的键:
当一个键被访问时,程序会对这个键进行检查,如果键已经过期,那么该键将被删除。
底层系统会在后台渐进地查找并删除那些过期的键,从而处理那些已经过期、但是不会被访问到的键。
当过期键被以上两个程序的任意一个发现、 并且将键从数据库中删除时, Redis 会产生一个 expired 通知。
Redis 并不保证生存时间(TTL)变为 0 的键会立即被删除: 如果程序没有访问这个过期键, 或者带有生存时间的键非常多的话, 那么在键的生存时间变为 0 , 直到键真正被删除这中间, 可能会有一段比较显著的时间间隔。
因此, Redis 产生expired通知的时间为过期键被删除的时候, 而不是键的生存时间变为 0 的时候。
三、案例
按上文内容,我们先将redis的键空间通知
开启,我们开启所有的通知,在可以端中测试后没问题再到代码中测试。
- 连接到redis 输入一下命令
config set notify-keyspace-events KEA
- 订阅键空间和键事件的主题
psubscribe '__key*__:*'#对所有库键空间通知psubscribe '__keyspace@2__:*' #是对db2数据库键空间通知psubscribe '__keyspace@2__:order*' #是对db2数据库,key前缀为order所有键的键空间通知
创建一个 key :name valus:zhangsan
set name wsl
观察订阅的窗口 会受到两个消息,第一个是:键空间 第二个是键事件,键空间是内容是操作指令,主题中包含有key,键事件主题中包含了指令,内容是key。
- 到这里说明已经开启了键空间通知
代码
以下代码采用string类型演示
在配置一下MessageListenerContainer
类,将我们写好的监听类添加到该类中即可,删除和过期都是需要添加,我这里就一起添加了后面就不做演示。
@Configuration
public class RedisConfig {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate RedisUpdateAndAddListener redisUpdateAndAddListener;@Autowiredprivate RedisDeleteListener redisDeleteListener;@Autowiredprivate RedisExpiredListener redisExpiredListener;@BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);//监听所有的key的set事件container.addMessageListener(redisUpdateAndAddListener, redisUpdateAndAddListener.getTopic());//监听所有key的删除事件container.addMessageListener(redisDeleteListener,redisDeleteListener.getTopic());//监听所有key的过期事件container.addMessageListener(redisExpiredListener,redisExpiredListener.getTopic());return container;}}
新增和修改都是set指令
所以监听的主题都一样,实现MessageListener
接口,重写onMessage
这里就是收到消息的处理逻辑
@Component
@Data
public class RedisUpdateAndAddListener implements MessageListener {//监听的主题private final PatternTopic topic = new PatternTopic("__keyevent@*__:set");@Overridepublic void onMessage(Message message,byte[] pattern){String topic = new String(pattern);String msg = new String(message.getBody());System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);}}
在redis中对name这个key进行set操作
set name wsl
在控制台就可以看到name这个key被操作了
删除
跟上面的更新监听一样,只需要把订阅主题更改一下即可。同样需要添加到这个RedisMessageListenerContainer
,上面已经添加,这里不做演示
@Component
@Data
public class RedisDeleteListener implements MessageListener {//监听主题private final PatternTopic topic = new PatternTopic("__keyevent@*__:del");/**** @param message 消息* @param pattern 主题*/@Overridepublic void onMessage(Message message, byte[] pattern) {String topic = new String(pattern);String msg = new String(message.getBody());System.out.println("收到key的删除,消息主题是:"+ topic+",消息内容是:"+msg);}
}
在redis输入命令,del name
在控制台可以看到已经收到消息了。
过期
如上面的操作方式一样
@Data
@Component
public class RedisExpiredListener implements MessageListener {//监听主题private final PatternTopic topic = new PatternTopic("__keyevent@*__:expired");@Overridepublic void onMessage(Message message, byte[] pattern) {String topic = new String(pattern);String msg = new String(message.getBody());System.out.println("收到key的过期,消息主题是:"+ topic+",消息内容是:"+msg);}
}
在redis中写一个定时删除的keySETEX age 18 3
三秒后就可以控制台打印了相关信息
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
SpringBoot监听redis Key变化事件详解相关推荐
- Spring Boot 监听 Redis Key 失效事件实现定时任务
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:彭超 https://antoniopeng.com 业务场 ...
- redis 能不能监听特定的key失效_Spring boot实现监听Redis key失效事件实现和其它方式...
1.pom 中添加依赖 org.springframework.boot spring-boot-starter-data-redis 2.定义配置RedisListenerConfig /** * ...
- springboot listener_Springboot 监听redis key的过期事件
项目中常常会碰到这样的需求,用户下订单后,30分钟未完成自动取消订单的功能. 有人说这个简单呀,写个定时任务就搞定了.除了定时任务之外,难道就没有其他的方法来实现吗?有--Redis 的键空间通知事件 ...
- redis 能不能监听特定的key失效_php监听redis key失效触发回调事件
订单超时.活动过期解决方案:php监听redis key失效触发回调事件 Redis 的 2.8.0 版本之后可用,键空间消息(Redis Keyspace Notifications),配合 2.0 ...
- php 监听redis,php监听redis key失效触发回调事件_后端开发
php中使用fsockopen实现异步请求(代码示例)_后端开发 php执行一段程序,有可能几毫秒就执行完毕,也有可能耗时较长.例如,用户下单这个事件,如果调用了些第三方服务进行发邮件.短信.推送等通 ...
- php 监听redis,php监听redis key失效触发回调事件
订单超时.活动过期解决方案:php监听redis key失效触发回调事件 Redis 的 2.8.0 版本之后可用,键空间消息(Redis Keyspace Notifications),配合 2.0 ...
- JavaScript监听DOM节点变化事件
JS监听页面DOM节点的变化 DOMSubtreeModified DOMNodeInserted DOMNodeRemoved DOMNodeInsertedIntoDocument DOMNode ...
- 监听Redis Key事件
文章目录 1.使用场景 2.使用 开启 redis 的事件监听与发布 Springboot集成 1.使用场景 处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态. 注意:只能适用于单机red ...
- SpringBoot监听redis过期key
开启过期监听 vim /etc/redis.conf 取消notify-keyspace-events Elg的注释 pom.xml 添加: <dependency><groupId ...
最新文章
- jdialog模态化
- .net core 引用jar_Python一键转Jar包,Java调用Python新姿势!
- 真格量化——做空波动率卖期权策略
- python读取大数据量xml_多快好省地使用pandas分析大型数据集
- 计算机算法设计与分析 递归实现快速排序和随机化实现快速排序
- java api接口签名验证失败_cryptapi结合java进行数字签名与验证签名的困惑
- STM32单片机雨滴模块
- 软考高项比中项在难度上高多少?
- 【笔记】lamp架构框图
- 信息安全数学基础-扩展欧式算法 2021.9.10
- 人民币转换美金的c语言代码大全,JS实现将人民币金额转换为大写的示例代码
- latex学习笔记——latex的字体字号设置
- 常用文本编辑器(NotePad++,UtraEdit)
- python调用oracle
- Azure媒体服务的Apple FairPlay流功能正式上线
- 被Linux之父骂醒?英伟达破天荒开源GPU内核驱动,网友:活久见
- 全球与中国洗地吸干机市场深度研究分析报告
- 3个免费、无损压缩图片的工具,一键解决图片过大问题
- android便签工具下载,小鱼便签软件下载-小鱼便签 安卓版v1.01.14-PC6安卓网
- IDEA 安装 mysql数据库 并访问 (Mac版)