diff --git a/中间件/redis/redis.md b/中间件/redis/redis.md index 5ac4012..5e43cda 100644 --- a/中间件/redis/redis.md +++ b/中间件/redis/redis.md @@ -186,6 +186,11 @@ - [Messages matching both a pattern and a channel subscription](#messages-matching-both-a-pattern-and-a-channel-subscription) - [the meaning of the subscription count with pattern matching](#the-meaning-of-the-subscription-count-with-pattern-matching) - [Sharded Pub/Sub](#sharded-pubsub) + - [Redis Keyspace notifaction](#redis-keyspace-notifaction) + - [Type of events](#type-of-events) + - [Configuration](#configuration) + - [Timing of expired events](#timing-of-expired-events) + - [Events in cluster](#events-in-cluster) # redis @@ -3100,3 +3105,73 @@ Sharded Pub/Sub能够帮助`Pub/Sub`在集群模式下的拓展。其将消息 > 在未引入`Shard Pub/Sub`机制之前,`Pub/Sub`的channel在集群中并不会被hash到slot。此时,`cluster中的每个node独立的维护订阅关系,不同节点之间的订阅并不共享`。并且,发送给某一节点的消息将会广播到整个cluster中所有的nodes。 +#### Redis Keyspace notifaction +Keyspace notification允许客户端针对`Pub/Sub channels`进行订阅,从而接收`events affecting the Redis data set`。 + +接收事件的示例如下: +- all the commands affecting a given key +- all the keys receiving an LPUSH operation +- all the keys expiring in the database 0 + +> 在使用`Pub/Sub`时,如果client失去了对redis的连接,并重新连接后,在client丢失连接的时间范围内,所有的事件都会丢失 + +##### Type of events +`keyspace notifications are implemented by sending two distinct types of events for every operation affecting the redis data space.` + +例如对`database 0`中的`meykey`执行的`DEL`操作,将会传递两个消息,等价于如下publish语句: +```redis-cli +PUBLISH __keyspace@0__:mykey del +PUBLISH __keyevent@0__:del mykey +``` +其中`__keyspace@0__:mykey`代表所有针对`mykey`的事件;`__keyevent@0__:del`只针对`mykey`的`del` operation。 + +第一种类型的事件,其channel名称包含keyspace prefix,被称为`key-space notification`。 + +第二种类型的事件,channel名称中包含keyevent prfix, 被称为`Key-event notification`。 + +在前面示例中,对mykey的del event生成了两条消息: +- `The key-space channel receives as message the name of the event` +- `The key-event channel receives as message the name of the key` + +##### Configuration +默认情况下,keyspace event notification处于disabled状态,因为其并非必须特性且会消耗部分CPU资源。可以通过`redis.conf`中的`notify-keyspace-events`配置或通过`CONFIG SET`来对其进行启用。 + +将该参数设置为空字符串会禁用notifications,为了启用该特性,需要将指定为非空,字符串由如下字符组成: +- 字符串中至少应该存在`K或E`,否则事件将不会被传递 +- 如果要对lists启用`key-space events`,那么可以配置为`Kl` +- 可以将参数设置为`KEA`为大部分data types启用events + +字符的含义如下表所示: +``` +K Keyspace events, published with __keyspace@__ prefix. +E Keyevent events, published with __keyevent@__ 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 generated when a key that doesn't exist is accessed (Note: not included in the 'A' class) +n New key events generated whenever a new key is created (Note: not included in the 'A' class) +o Overwritten events generated every time a key is overwritten (Note: not included in the 'A' class) +c Type-changed events generated every time a key's type changes (Note: not included in the 'A' class) +A Alias for "g$lshztdxe", so that the "AKE" string means all the events except "m", "n", "o" and "c". +``` + +##### Timing of expired events +如果key存在`ttl`,那么redis将会在如下两种时机下让key过期: +- 当key被command访问,并发现key过期 +- 当backgroud system查找到expired keys + +当key通过上述两种机制之一被发现过期时,会生成expired events。redis`并不保证`在key的ttl到期后`立马`会产生expired event。 + +如果该key未持续被command访问,且同时存在多个key关联ttl,那么`the key time to live drops to zero`的时间和`the exipred event`生成的时间可能存在较大的延迟。 + +`Expired events`将会在redis server删除key时被生成,并非`ttl`减为0的时间。 + +##### Events in cluster +redis cluster中的每个node都会生成其自己的keyspace相关事件。但是,和集群环境下`Pub/Sub`机制不同的是,`events notifications`并不会被广播到cluster中的其他节点。keyspace events是`node-specific`的,从cluster接收到所有的keyspace events时,clients需要为每个node都进行订阅。 \ No newline at end of file