从Redis 2.8.0开始,Redis加入了发布/订阅模式以及键空间消息提醒(keyspace notification)功能。键空间消息提醒提供了允许客户端通过订阅指定信道获取Redis数据变化的能力。
需要注意的是,键空间消息提醒并非可靠的,它不会对订阅端是否接收到消息进行确认。例如某个订阅的客户端暂时断开连接,在其直到恢复连接期间发生的事件将无法再次获得。
配置
在默认情况下,Redis并未开启键空间消息提醒功能。为了打开该功能,需要通过notify-keyspace-events
配置进行设置,例如:
redis> CONFIG GET notify-keyspace-events
1) "notify-keyspace-events"
2) ""
redis> CONFIG SET notify-keyspace-events KEA
OK
redis> CONFIG GET notify-keyspace-events
1) "notify-keyspace-events"
2) "AKE"
在上述示例中将notify-keyspace-events
配置为KEA
,代表除未命中外的所有事件。其中,K
与E
代表事件的两种类型——Keyspace
与Keyevent
。Keyspace
代表与事件名称相关的消息,例如订阅对指定键进行的操作事件;Keyevent
代表与键名称相关的消息,例如订阅发生键过期事件的相关键名称。
关于更多的notify-keyspace-events
配置,可参考下面的描述:
K
:Keyspace事件,将会以__keyspace@<db>__
作为事件的前缀E
:Keyevent事件,将会以__keyevent@<db>__
作为事件的前缀g
:非特定类型的通用命令,例如DEL
、EXPIRE
、RENAME
等$
:字符串命令,例如SET
、INCR
等l
:列表命令,例如LPUSH
、LPOP
等s
:集合命令,例如SADD
、SREM
等h
:哈希表命令,例如HSET
、HINCRBY
等z
:有序集合命令,例如ZSET
、ZREM
等t
:流命令,例如XADD
、XDEL
等x
:过期事件(在每个发生键过期的时候产生)e
:淘汰事件(在每个发生键被淘汰的时候产生)m
:未命中事件(在访问某个不存在的键时产生)A
:配置g$lshztxe
的别名,但不包括未命中事件m
订阅指定事件
在完成配置后,可通过SUBSCRIBE
命令订阅指定信道实现对一个或多个指定事件的订阅。例如通过订阅__keyevent@0__:expired
实现订阅数据库0中的键过期事件例如示例1:订阅键过期事件。
订阅的信道的格式为__<type>@<db>__:<event>
,其包括了事件类型(keyspace
或keyevent
)、数据库(例如数据库0
)以及事件(例如expired
)三部分组成。对应事件的名称,可参考下文命令事件章节。
另外,也可以通过PSUBSCRIBE
命令订阅一个或多个复合正则表达式匹配的信道。例如通过订阅__key*@*__:*
订阅Redis中所有数据库中的所有事件。
命令事件
Redis为许多命令提供了不同的事件,在本文中将选择其中部分命令及其对应的事件进行介绍:
DEL
:在某个键被删除时产生del
事件EXPIRE
、PEXPIRE
、EXPIREAT
以及PEXPIREAT
:当设置正数过期时间或未来时间的时间戳,则产生expire
事件,否则产生del
事件(将立即被删除)SET
以及同类的SETEX
、SETNX
、GETSET
:产生set
事件,若使用SETEX
则也会产生expire
事件MSET
:将会为每个键都产生一个set
事件LPUSH
、LPUSHX
与RPUSH
、RPUSHX
:根据插入的方向分别产生lpush
或rpush
事件RPOP
、LPOP
:分别产生rpop
与lpop
事件,若移出的是列表中的最后一个元素,将会同时产生del
事件LSET
:产生lset
事件LREM
:产生lrem
事件,同样若移除的元素为列表中的最后一个元素时将同时产生del
事件HSET
、HSETNX
以及HMSET
:产生一个hset
事件HDEL
:产生一个hdel
事件,且在移除后哈希表为空的情况下产生del
事件SADD
:产生一个sadd
事件SREM
:产生一个srem
事件,且在移除后集合为空的情况下产生del
事件SMOVE
:原键中产生srem
事件且在目标键中产生sadd
事件SINTERSTORE
、SUNIONSTORE
、SDIFFSTORE
:分别产生sinterstore
、sunionstore
以及sdiffstore
事件,且在结果为空集且目标键存在的情况下,将会产生del
事件ZADD
:无论添加几个元素都只产生一个zadd
事件ZREM
:无论移除几个元素都只产生一个zrem
事件,当移除后有序集合为空时产生del
事件XADD
:产生xadd
事件,若使用MAXLEN
子命令可能会同时产生xtrim
事件XDEL
:产生xdel
事件PERSIST
:如果对应的键所关联的过期事件成功被移除,则产生persist
事件- 在键发生过期时产生
expired
事件 - 在达到
maxmemory
设定的内存值后发生键淘汰时产生evicted
事件 - ……
关于更多的命令相关事件,请参考keyspace notification相关文档
示例
订阅键过期事件
redis1> SUBSCRIBE __keyevent@0__:expired
1) "subscribe"
2) "__keyevent@0__:expired"
3) (integer) 1
# redis2> SETEX greeting 1 "hello world"
# 等待1秒后:
1) "message"
2) "__keyevent@0__:expired"
3) "greeting"
订阅所有事件
redis1> PSUBSCRIBE __key*@*__:*
1) "psubscribe"
2) "__key*@*__:*"
3) (integer) 1
# redis2> SET greeting "hello world"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyspace@0__:greeting"
4) "set"
1) "pmessage"
2) "__key*@*__:*"
3) "__keyevent@0__:set"
4) "greeting"