Redis键空间通知(Keyspace Notifications)

键空间通知(Keyspace Notification)是一个从Redis 2.8.0版本开始可用的功能。

1、简介:

键空间通知基于订阅Pub/Sub(发布/订阅),当库中的key发生改变时,能够对你感兴趣的事件进行通知。

可能接收到的事件示例,如下所示:

  • 所有影响到一个给定键的命令。
  • 所有接收到一个LPUSH命令的键。
  • 所有数据库-0中的键全都过期。

注:因为Redis的Pub/Sub功能当前是“触发后不管(Fire and Forget)”的,所以如果你的应用程序需要的是可靠的消息通知,那么它就不能使用Redis的键空间通知功能。也就是说,如果你的Pub/Sub客户端断开连接,然后再重新连接,那么在客户端断开连接的期间内传递的所有事件都会丢失。

 2、通知类型:

对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件。以set操作为例,当在数据库-0中的添加一个名为key1的键时,将会触发Redis传递两条消息,完全等价于下面两条PUBLISH命令:

publish __keyspace@0__:key1 set
publish __keyevent@0__:set key1

我们简单地看一下这两条命令,keyspace表示键空间通知,keyevent表示键事件通知。

  • keyspace:键空间通知,监听的频道/通道是 当前库的编号 __:操作的key ,消息的内容是事件的名称
  • keyevent:键事件通知,监听的频道/通道是当前库的编号__:事件的名称,消息的内容是操作的key

以 keyspace 为前缀的频道被称为键空间通知(key-space notification), 而以 keyevent 为前缀的频道则被称为键事件通知(key-event notification)。

为了只对我们感兴趣的事件进行监听,我们需要对notify-keyspace-events进行配置。

3、配置notify-keyspace-events

在默认情况下,键空间的事件通知功能是禁用的(notify-keyspace-events “”),因为这个功能会消耗一些CPU性能,虽然几乎感觉不到性能消耗。有两种方法可以启用通知功能:修改redis.conf文件的notify-keyspace-events参数,或者使用CONFIG SET命令。接下来看看具体如何对notify-keyspace-events进行配置:

It is possible to select the events that Redis will notify among a set
 of classes. Every class is identified by a single character:

  K     Keyspace events, published with <db>__ prefix.
     键空间(Keyspace)事件,通过<db>__前缀的频道发布。
  E     Keyevent events, published with <db>__ prefix.
     键事件(Keyevent)事件,通过<db>__前缀的频道发布。

  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
     通用的命令(不特定类型),例如:DEL、EXPIRE、RENAME,等等。
  $     String commands
        对字符串相关命令进行发布
  l     List commands
        对列表相关命令进行发布
  s     Set commands
        对集合相关命令进行发布
  h     Hash commands
        对哈希相关命令进行发布
  z     Sorted set commands
        对有序集合相关命令进行发布
  x     Expired events (events generated every time a key expires)
        过期事件(每当一个键过期时,对这个键的过期事件进行发布)
  e     Evicted events (events generated when a key is evicted for maxmemory)
        内存回收事件(当达到最大内存,然后回收某个键的内存时,对这个件的内存回收事件进行发布)。
  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
        g$lshzxe的别名。因此,“AKE”字符串可以表示所有的事件。

notify-keyspace-events ""

配置字符串至少应当包含KE字符。否则,即使这个字符串包含其他任何字符,Redis也不会传递任何事件。

例如我们只想要对字符串操作进行监听,并且只想通过键事件通知进行监听,那么我们可以这么配:“E$“;如果想监听所有事件可以配置为“AKE”。

4、不同命令产生的事件

命令产生的事件
DEL这个命令会为每个被删除的键产生一个del事件。
RENAME这个命令会产生两个事件,一个为原始键产生的rename_from事件,以及一个为目标键产生的rename_to事件。
EXPIRE当为某个键设置过期时间时,这个命令便会产生一个expire事件;或者,每当为某个待删除的键设置一个过期结果时,这个命令便会产生一个expired事件(请参考EXPIRE命令的相关文档)。
SORT当使用STORE选项来设置一个新键时,这个命令便会产生一个sortstore事件。如果结果列表为空,并且使用了STORE选项,并且已经存在一个同名的键,那么Redis便会删除这个已有的键,在这种情况下,这个命令还会产生一个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事件。这两个事件的产生顺序都是固定不变的,先产生rpop事件,然后再产生lpush事件。另外,如果运行这两个命令之后,列表变为空表,那么便会删除这个列表对应的键,此时还会产生一个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

这些命令会分别产生si<span>nterstore</span>sunionostoresdiffstore事件。在特殊情况下,如果运行这些命令得到的集合为空,并且用于存储结果的键已经存在,那么这个键将会被删除,然后还会产生一个del事件。
ZINCRBY这个命令会产生一个zincr事件。
ZADD这个命令会产生一个zadd事件,即使有多个输入元素时,也是如此。
ZREM这个命令会产生一个zrem事件,即使需要删除多个元素时,也是如此。如果运行这个命令之后,有序集合变为空,那么便会删除这个有序集合对应的键,此时还会产生一个del事件。
ZREMRANGEBYSCORE这个命令会产生一个zrembyscore事件。如果运行这个命令之后,有序集合变为空,那么便会删除这个有序集合对应的键,此时还会产生一个del事件
ZREMRANGEBYRANK这个命令会产生一个zrembyrank事件。如果运行这个命令之后,有序集合变为空,那么便会删除这个有序集合对应的键,此时还会产生一个del事件。
ZINTERSTORE、ZUNIONSTORE这两个命令会分别产生zinterstorezunionstore事件。在特殊情况下,如果运行这些命令得到的有序集合为空,并且用于存储结果的键已经存在,那么这个键将会被删除,然后还会产生一个del事件。

当然,你也可以将notify-keyspace-events 设置为"AKE",然后对各种命令进行尝试,通过订阅__key*__:*即可接收到所有操作的消息。


参考:https://zhuanlan.zhihu.com/p/103963089