SpringBoot监听redis,Key的新增、删除、修改、过期事件(详细)
键空间通知(keyspace notification)如果你不知道redis的键空间通知需耐⼼看完如下内容再看代码,如果你知道则可以跳过
功能概览
键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种⽅式改动了 Redis 数据集的事件。
以下是⼀些键空间通知发送的事件的例⼦:
所有修改键的命令。
所有接收到 LPUSH key value [value …] 命令的键。
0 号数据库中所有已过期的键。
事件通过 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 , 所以在默认配置下, 该功能处于关闭状态。
可以通过修改 f ⽂件, 或者直接使⽤ CONFIG SET 命令来开启或关闭键空间通知功能:
当 notify-keyspace-events 选项的参数为空字符串时,功能关闭。
另⼀⽅⾯,当参数不是空字符串时,功能开启。
notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:
输⼊的参数中⾄少要有⼀个 K或者 E , 否则的话, 不管其余的参数是什么, 都不会有任何通知被分发。
举个例⼦, 如果只想订阅键空间中和列表相关的通知, 那么参数就应该设为 Kl , 诸如此类。
将参数设为字符串"AKE" 表⽰发送所有类型的通知。
命令产⽣的通知
以下列表记录了不同命令所产⽣的不同通知:
DEL key [key …] 命令为每个被删除的键产⽣⼀个del 通知。
RENAME key newkey 产⽣两个通知:为来源键(source key)产⽣⼀个 rename_from 通知,并为⽬标键(destination key)产⽣⼀个 rename_to通知。
EXPIRE key conds 和 EXPIREAT key timestamp 在键被正确设置过期时间时产⽣⼀个 expire 通知。当 EXPIREAT key timestamp 设置的时间已经过期,或者 EXPIRE key conds 传⼊的时间为负数值时,键被删除,并产⽣⼀个 del 通知。
SORT key [BY pattern] [LIMIT offt count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA] [STORE destination]在命令带有 STORE 参数时产⽣⼀个 sortstore 事件。如果 STORE 指⽰的⽤于保存排序结果的键已经存在,那么程序还会发送⼀个 del 事件。
SET key value [EX conds] [PX milliconds] [NX|XX] 以及它的所有变种(SETEX key conds val
ue 、 SETNX key value 和GETSET key value)都产⽣ t 通知。其中 SETEX key conds value 还会产⽣ expire通知。
MSET key value [key value …]为每个键产⽣⼀个 t 通知。
SETRANGE key offt value 产⽣⼀个 trange 通知。
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 valu e 都产⽣单个 rpush 通知,即使有多个输⼊元素时,也是如此。
RPOP key 产⽣rpop通知。如果被弹出的元素是列表的最后⼀个元素,那么还会产⽣⼀个 del 通知。
LPOP key产⽣lpop通知。如果被弹出的元素是列表的最后⼀个元素,那么还会产⽣⼀个 del 通知。
LINSERT key BEFORE|AFTER pivot value 产⽣⼀个 linrt 通知。
LINSERT key BEFORE|AFTER pivot value 产⽣⼀个 linrt 通知。
LSET key index value 产⽣⼀个 lt 通知。
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 都只产⽣⼀个 ht 通知。
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 通知。
每当⼀个键因为过期⽽被删除时,产⽣⼀个 expired 通知。
每当⼀个键因为maxmemory政策⽽被删除以回收内存时,产⽣⼀个 evicted 通知。
人造美女小游戏所有命令都只在键真的被改动了之后,才会产⽣通知。
⽐如说,当 SREM key member [member …]试图删除不存在于集合的元素时,删除操作会执⾏失败,因为没有真正的改动键,所以这⼀操作不会发送通知。
如果对命令所产⽣的通知有疑问, 最好还是使⽤以下命令, ⾃⼰来验证⼀下:
Redis 使⽤以下两种⽅式删除过期的键:
当⼀个键被访问时,程序会对这个键进⾏检查,如果键已经过期,那么该键将被删除。
底层系统会在后台渐进地查找并删除那些过期的键,从⽽处理那些已经过期、但是不会被访问到的键。
当过期键被以上两个程序的任意⼀个发现、 并且将键从数据库中删除时, Redis 会产⽣⼀个 expired 通知。
neutralized
Redis 并不保证⽣存时间(TTL)变为 0 的键会⽴即被删除: 如果程序没有访问这个过期键, 或者带有⽣存时间的键⾮常多的话, 那么在键的⽣存时间变为 0 , 直到键真正被删除这中间, 可能会有⼀段⽐较显著的时间间隔。
因此, Redis 产⽣expired通知的时间为过期键被删除的时候, ⽽不是键的⽣存时间变为 0 的时候。
考研时间安排2016案例
按上⽂内容,我们先将redis的键空间通知开启,我们开启所有的通知,在可以端中测试后没问题再到代码中测试。
连接到redis 输⼊⼀下命令
mama said
config t notify-keyspace-events KEA
订阅键空间和键事件的主题
psubscribe '__key*__:*'
创建⼀个 key :name valus:wlsbaritone
t name wsl
观察订阅的窗⼝ 会受到两个消息,第⼀个是:键空间 第⼆个是键事件,键空间是内容是操作指令,主题中包含有key,键事件主题中包含了指令,内容是key。
雅思托福到这⾥说明已经开启了键空间通知
代码
以下代码采⽤string类型演⽰
新增、修改
新增和修改都是t指令,所以监听的主题都⼀样,实现MessageListener接⼝,重写onMessage这⾥就是收到消息的处理逻辑
@Component
@Data
public class RedisUpdateAndAddListener implements MessageListener {
//监听的主题
private final PatternTopic topic =new PatternTopic("__keyevent@*__:t");
@Override
public void onMessage(Message message,byte[] pattern){
inferior
String topic =new String(pattern);
String msg =new Body());
System.out.println("收到key更新或修改,消息主题是:"+ topic+",消息内容是:"+msg);
}
}
在配置⼀下MessageListenerContainer类,将我们写好的监听类添加到该类中即可,删除和过期都是需要添加,我这⾥就⼀起添加了后⾯就不做演⽰。北京日语翻译