Redis 密钥空间通知
实时监控 Redis 键和值的更改
Keyspace 通知允许客户端按顺序订阅 Pub/Sub 频道 接收以某种方式影响 Redis 数据集的事件。
可以接收的事件示例包括:
- 影响给定键的所有命令。
- 所有接收 LPUSH作的 key。
- 数据库 0 中过期的所有键。
注意:Redis Pub/Sub 是即发即弃;也就是说,如果您的 Pub/Sub 客户端断开连接, 并在稍后重新连接客户端 disconnected 会丢失。
事件类型
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 通道以消息形式接收事件的名称。
- Key-event 通道以消息形式接收键的名称。
可以只启用一种通知才能传递 只是我们感兴趣的事件子集。
配置
默认情况下,密钥空间事件通知是禁用的,因为虽然没有
非常明智的该功能使用了一些 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" and "n".
至少K
或E
应存在于字符串中,否则无事件
将传递,而不管字符串的其余部分如何。
例如,要仅为列表启用 Key-space 事件,则配置
parameter 必须设置为Kl
等。
您可以使用字符串KEA
以启用大多数类型的事件。
由不同命令生成的事件
不同的命令根据以下列表生成不同类型的事件。
APPEND
生成一个append
事件。COPY
生成一个copy_to
事件。DEL
生成一个del
事件。EXPIRE
及其所有变体 (PEXPIRE
,EXPIREAT
,PEXPIREAT
) 生成一个expire
event 调用时,使用正超时(或将来的时间戳)调用。请注意,当使用过去的负超时值或时间戳调用这些命令时,将删除该键,并且只有del
event 的 EVENT。HDEL
生成单个hdel
事件和附加的del
事件(如果生成的哈希为空并且 key 被删除)。HEXPIRE
及其所有变体 (HEXPIREAT
,HPEXPIRE
,HPEXPIREAT
) 生成hexpire
事件。此外hexpired
当字段过期时生成事件。HINCRBYFLOAT
生成一个hincrbyfloat
事件。HINCRBY
生成一个hincrby
事件。HPERSIST
生成一个hpersist
事件。HSET
,HSETNX
和HMSET
都会生成一个hset
事件。INCRBYFLOAT
生成一个incrbyfloat
事件。INCR
,DECR
,INCRBY
,DECRBY
命令都生成incrby
事件。LINSERT
生成一个linsert
事件。LMOVE
和BLMOVE
生成一个lpop
/rpop
事件(取决于 wherefrom 参数)和lpush
/rpush
事件(取决于 whereto 参数)。在这两种情况下,顺序都是有保证的(lpush
/rpush
事件将始终在lpop
/rpop
事件)。此外,一个del
如果结果列表的长度为零,并且 key 被删除,则将生成 event 。LPOP
生成一个lpop
事件。此外,一个del
event 如果由于弹出了列表中的最后一个元素而被删除了键。LPUSH
和LPUSHX
生成单个lpush
事件,即使在可变参数情况下也是如此。LREM
生成一个lrem
事件,此外还有一个del
事件(如果结果列表为空且键被删除)。LSET
生成一个lset
事件。LTRIM
生成一个ltrim
事件,此外还有一个del
事件(如果结果列表为空且键被删除)。MIGRATE
生成一个del
事件(如果源键已删除)。MOVE
生成两个事件,一个move_from
event 作为源键,并使用move_to
event 作为目标键。MSET
生成一个单独的set
event 的 intent 中。PERSIST
生成一个persist
event 如果已成功删除与密钥关联的过期时间。RENAME
生成两个事件,一个rename_from
event 作为源键,并使用rename_to
event 作为目标键。RESTORE
生成一个restore
event 的密钥。RPOPLPUSH
和BRPOPLPUSH
生成一个rpop
event 和lpush
事件。在这两种情况下,顺序都是有保证的(lpush
事件将始终在rpop
事件)。此外,一个del
如果结果列表的长度为零,并且 key 被删除,则将生成 event 。RPOP
生成一个rpop
事件。此外,一个del
event 如果由于弹出了列表中的最后一个元素而被删除了键。RPUSH
和RPUSHX
生成单个rpush
事件,即使在可变参数情况下也是如此。SADD
生成单个sadd
事件,即使在可变参数情况下也是如此。SETRANGE
生成一个setrange
事件。SET
及其所有变体 (SETEX
,SETNX
,GETSET
) 生成set
事件。然而SETEX
还将生成一个expire
事件。SINTERSTORE
,SUNIONSTORE
,SDIFFSTORE
生成sinterstore
,sunionstore
,sdiffstore
事件。在特殊情况下,结果集为空,并且存储结果的 key 已经存在,一个del
事件,因为密钥被删除。SMOVE
生成一个srem
event 作为源键,并使用sadd
event 作为目标键。SORT
生成一个sortstore
event 时STORE
用于设置新密钥。如果结果列表为空,并且STORE
选项,并且已经存在具有该名称的现有键,则结果是该键被删除,因此del
事件。SPOP
生成一个spop
事件和附加的del
event,如果结果集为空且 key 被删除。SREM
生成单个srem
事件和附加的del
event,如果结果集为空且 key 被删除。XADD
生成一个xadd
事件,可能在xtrim
event 与MAXLEN
子命令。XDEL
生成单个xdel
事件,即使删除了多个条目。XGROUP CREATECONSUMER
生成一个xgroup-createconsumer
事件。XGROUP CREATE
生成一个xgroup-create
事件。XGROUP DELCONSUMER
生成一个xgroup-delconsumer
事件。XGROUP DESTROY
生成一个xgroup-destroy
事件。XGROUP SETID
生成一个xgroup-setid
事件。XSETID
生成一个xsetid
事件。XTRIM
生成一个xtrim
事件。ZADD
生成单个zadd
事件,即使添加了多个元素也是如此。ZDIFFSTORE
,ZINTERSTORE
和ZUNIONSTORE
分别生成zdiffstore
,zinterstore
和zunionstore
事件。在特殊情况下,结果排序集为空,并且存储结果的键已经存在,一个del
事件,因为密钥被删除。ZINCRBY
生成一个zincr
事件。ZREMRANGEBYRANK
生成单个zrembyrank
事件。当生成的排序集为空并且生成了键时,附加的del
事件。ZREMRANGEBYSCORE
生成单个zrembyscore
事件。当生成的排序集为空并且生成了键时,附加的del
事件。ZREM
生成单个zrem
事件,即使删除了多个元素也是如此。当生成的排序集为空并且生成了键时,附加的del
事件。- 每次从数据集中删除具有生存时间关联的键时,都会触发一个
expired
事件。 - 每次从数据集中逐出键以释放内存时,由于
maxmemory
policy、evicted
事件。 - 每次将新键添加到数据集时,都会显示一个
new
事件。
重要 仅当目标键确实被修改时,所有命令才会生成事件。例如,SREM
从 Set 中删除不存在的元素实际上不会更改 key 的值,因此不会生成任何事件。
如果对如何为给定命令生成事件有疑问,最简单的 要做的是观察自己:
$ 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
event 时,关键生存时间达到零值。
如果没有命令始终以密钥为目标,并且有许多密钥与 TTL 相关联,则密钥生存时间降至零的时间与expired
事件。
已过期 (expired
) 事件是在 Redis 服务器删除键时生成,而不是在理论生存时间达到零值时生成。
集群中的事件
如上所述,Redis 集群的每个节点都会生成有关其自己的键空间子集的事件。但是,与集群中的常规 Pub/Sub 通信不同,事件的通知不会广播到所有节点。换句话说,键空间事件是特定于节点的。这意味着要接收集群的所有密钥空间事件,客户端需要订阅每个节点。
@history
>= 6.0
:添加了关键未命中事件。>= 7.0
:事件类型new
添加