# Redis 键空间通知
实时监控 Redis 键和值的变化
Keyspace 通知允许客户端订阅 Pub/Sub 频道,以便接收以某种方式影响 Redis 数据集的事件。
可以接收的事件示例如下:
- 影响给定键的所有命令。
- 所有接受 LPUSH 操作的键。
- 数据库 0 中所有过期的密钥。
注意:Redis Pub/Sub 很火,忘记了,如果您的 Pub/Sub 客户端断开连接,然后重新连接,则在客户端断开连接期间传递的所有事件都将丢失。
# 活动类型
Keyspace 通知是通过为影响 Redis 数据空间的每个操作发送两种不同类型的事件来实现的。例如,针对数据库 DEL
中命名的键的操作将触发两条消息的传递,完全等同于以下两个 命令:mykey``0
PUBLISH
PUBLISH __keyspace@0__:mykey del
PUBLISH __keyevent@0__:del mykey
第一个通道监听所有针对按键的事件mykey
,另一个通道只监听del
按键上的操作事件mykey
第一种keyspace
在通道中带有前缀的事件称为Key-space 通知,而第二种带有keyevent
前缀的事件称为Key-event 通知。
在前面的示例del
中,为键生成了一个事件,mykey
导致两条消息:
- Key-space 通道接收事件名称作为消息。
- 键事件通道接收键名称作为消息。
可以只启用一种通知,以便只传递我们感兴趣的事件子集。
# 配置
默认情况下,键空间事件通知被禁用,因为虽然不是很明智,但该功能使用了一些 CPU 能力。notify-keyspace-events
使用redis.conf 或通过CONFIG SET启用通知。
将参数设置为空字符串会禁用通知。为了启用该功能,使用了一个由多个字符组成的非空字符串,其中每个字符根据下表具有特殊含义:
K Keyspace events, published with __keyspace@<db>__ prefix.
E Keyevent events, published with __keyevent@<db>__ prefix.
g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
$ String commands
l List commands
s Set commands
h Hash commands
z Sorted set commands
t Stream commands
d Module key type events
x Expired events (events generated every time a key expires)
e Evicted events (events generated when a key is evicted for maxmemory)
m Key miss events (events generated when a key that doesn't exist is accessed)
n New key events (Note: not included in the 'A' class)
A Alias for "g$lshztxed", so that the "AKE" string means all the events except "m".
至少K
或E
应该存在于字符串中,否则无论字符串的其余部分如何,都不会传递任何事件。
例如,要仅启用列表的键空间事件,必须将配置参数设置为Kl
,依此类推。
您可以使用该字符串KEA
来启用大多数类型的事件。
# 不同命令产生的事件
根据以下列表,不同的命令会生成不同类型的事件。
DEL
del
为每个已删除的键生成一个事件。RENAME
生成两个事件,rename_from
源键rename_to
事件和目标键事件。MOVE
生成两个事件,move_from
源键move_to
事件和目标键事件。COPY
产生一个copy_to
事件。MIGRATE
del
如果源密钥被删除,则生成一个事件。RESTORE
为键生成restore
事件。EXPIRE
并且它的所有变体(PEXPIRE
,EXPIREAT
, )在使用正超时(或未来时间戳)调用时都会PEXPIREAT
生成一个事件。expire
请注意,当过去使用负超时值或时间戳调用这些命令时,会删除键,而只会del
生成一个事件。SORT
当用于设置新密钥时生成一个sortstore
事件。STORE
如果结果列表为空,并且STORE
使用了该选项,并且已经存在具有该名称的键,则结果是键被删除,因此del
在这种情况下会生成一个事件。SET
及其所有变体 (SETEX
,SETNX
,GETSET
) 都会生成set
事件。但是SETEX
也会产生一个expire
事件。MSET
set
为每个键生成一个单独的事件。SETRANGE
产生一个setrange
事件。INCR
,DECR
,INCRBY
,DECRBY
命令都生成incrby
事件。INCRBYFLOAT
产生一个incrbyfloat
事件。APPEND
产生一个append
事件。LPUSH
并LPUSHX
生成单个lpush
事件,即使在可变参数情况下也是如此。RPUSH
并RPUSHX
生成单个rpush
事件,即使在可变参数情况下也是如此。RPOP
产生一个rpop
事件。此外,del
如果由于弹出列表中的最后一个元素而删除了键,则会生成一个事件。LPOP
产生一个lpop
事件。此外,del
如果由于弹出列表中的最后一个元素而删除了键,则会生成一个事件。LINSERT
产生一个linsert
事件。LSET
产生一个lset
事件。LREM
生成一个lrem
事件,del
如果结果列表为空并且删除了键,则生成一个事件。LTRIM
生成一个ltrim
事件,del
如果结果列表为空并且删除了键,则生成一个事件。RPOPLPUSH
并BRPOPLPUSH
生成一个rpop
事件和一个lpush
事件。在这两种情况下,订单都是有保证的(lpush
事件总是在rpop
事件之后交付)。此外,del
如果结果列表的长度为零并且密钥被删除,则将生成一个事件。LMOVE
并BLMOVE
生成lpop
/rpop
事件(取决于 wherefrom 参数)和lpush
/rpush
事件(取决于 whereto 参数)。在这两种情况下,订单都是有保证的(lpush
/rpush
事件将始终在lpop
/rpop
事件之后交付)。此外,del
如果结果列表的长度为零并且密钥被删除,则将生成一个事件。HSET
,HSETNX
并且HMSET
都生成一个hset
事件。HINCRBY
产生一个hincrby
事件。HINCRBYFLOAT
产生一个hincrbyfloat
事件。HDEL
生成单个事件,如果生成的哈希为空并且删除了键,则生成hdel
一个附加事件。del
SADD
生成单个sadd
事件,即使在可变参数情况下也是如此。SREM
生成单个事件,如果结果集为空且删除键,则生成srem
附加事件。del
SMOVE
srem
为源键生成一个事件,sadd
为目标键生成一个事件。SPOP
生成一个事件,如果结果集为空并且删除了键,则生成spop
一个附加事件。del
SINTERSTORE
,SUNIONSTORE
,分别SDIFFSTORE
生成sinterstore
,sunionstore
,sdiffstore
事件。在特殊情况下,结果集为空,并且存储结果的 key 已经存在,del
由于 key 被删除,将生成一个事件。ZINCR
产生一个zincr
事件。ZADD
zadd
即使添加了多个元素,也会生成单个事件。ZREM
zrem
即使删除了多个元素,也会生成单个事件。当结果排序集为空并生成键时,会生成一个附加del
事件。ZREMBYSCORE
生成单个zrembyscore
事件。当结果排序集为空并生成键时,会生成一个附加del
事件。ZREMBYRANK
生成单个zrembyrank
事件。当结果排序集为空并生成键时,会生成一个附加del
事件。ZDIFFSTORE
,ZINTERSTORE
并ZUNIONSTORE
分别生成zdiffstore
,zinterstore
和zunionstore
事件。在特殊情况下,结果排序集为空,并且存储结果的键已经存在,del
因为键被删除,所以会产生一个事件。XADD
生成一个事件,当与子命令一起使用时xadd
,可能会跟随一个事件。xtrim``MAXLEN
XDEL
xdel
即使删除了多个条目,也会生成单个事件。XGROUP CREATE
产生一个xgroup-create
事件。XGROUP CREATECONSUMER
产生一个xgroup-createconsumer
事件。XGROUP DELCONSUMER
产生一个xgroup-delconsumer
事件。XGROUP DESTROY
产生一个xgroup-destroy
事件。XGROUP SETID
产生一个xgroup-setid
事件。XSETID
产生一个xsetid
事件。XTRIM
产生一个xtrim
事件。PERSIST
persist
如果与密钥关联的到期时间已成功删除,则生成事件。- 每次由于过期而从数据集中删除与生存时间相关联的密钥时,
expired
都会生成一个事件。 - 每次从数据集中逐出一个键以作为
maxmemory
策略的结果释放内存时,都会生成一个evicted
事件。 - 每次向数据集中添加新键时,
new
都会生成一个事件。
重要的是,只有在真正修改了目标键时,所有命令才会生成事件。例如, SREM
从 Set 中删除不存在的元素实际上不会更改键的值,因此不会生成任何事件。
如果对给定命令如何生成事件有疑问,最简单的做法是观察自己:
$ redis-cli config set notify-keyspace-events KEA
$ redis-cli --csv psubscribe '__key*__:*'
Reading messages... (press Ctrl-C to quit)
"psubscribe","__key*__:*",1
此时redis-cli
在另一个终端中使用向 Redis 服务器发送命令并观察生成的事件:
"pmessage","__key*__:*","__keyspace@0__:foo","set"
"pmessage","__key*__:*","__keyevent@0__:set","foo"
...
# 过期事件的时间
Redis 以两种方式使与生存时间相关联的密钥过期:
- 当密钥被命令访问并发现已过期时。
- 通过后台系统在后台逐步查找过期密钥,以便能够收集从未访问过的密钥。
这些expired
事件是在访问某个密钥并被上述系统之一发现已过期时生成的,因此无法保证 Redis 服务器能够expired
在密钥生存时间到达时生成事件值为零。
如果没有命令始终以键为目标,并且有许多键与 TTL 相关联,则在键的生存时间下降到零的时间与expired
生成事件的时间之间可能会有很大的延迟。
基本上,expired
事件**是在 Redis 服务器删除键时生成的,**而不是在理论上生存时间达到零值时生成的。
# 集群中的事件
如上所述,Redis 集群的每个节点都会生成有关其自己的键空间子集的事件。但是,与集群中的常规 Pub/Sub 通信不同,事件的通知不会广播到所有节点。换句话说,键空间事件是特定于节点的。这意味着要接收集群的所有键空间事件,客户端需要订阅每个节点。
@历史
>= 6.0
:增加了关键未命中事件。>= 7.0``new
:添加事件类型
# 反馈
如果您在此页面上发现问题,或有改进建议,请提交请求以合并或打开存储库中的问题。