Redis键空间事件通知
Categories:
Redis键空间事件通知
从Redis 2.8.0 开始 键空间通知允许客户端订阅发布/订阅信道来接收以某种方式影响Redis数据集的事件
由于Redis的发布/订阅当前是发后即忘模式的,因此如果你的应用需要可靠的事件通知,则无法满足,也就是说,
如果你的发布/订阅客户端断开连接并在稍后重连,客户端断开的这段时间内的所有事件通知都会丢失。
空间事件通知
键空间通知被实现成对每个影响Redis数据集的操作发送两个不同类型的事件。例如,一个在0号数据库中对名称为mykey的键执行DEL操作将触发推送两条消息,
相当于执行了下面两条PUBLISH命令:
PUBLISH keyspace@0:mykey del
PUBLISH keyevent@0:del mykey
很容易看出一个信道可以监听所有针对键mykey的事件,另一个信道允许获取对所有键执行删除操作的信息。
第一类事件,以keyspace为前缀的信道被称为键-空间通知,
第二类事件,以keyevent为前缀的信道被称为键-事件通知。
Redis配置
默认情况下,键空间事件通知是被禁用的,因为这个功能会消耗一些CPU,默认打开是不明智的。可以在redis.conf文件中使用notify-keyspace-events或CONFIG SET命令启用它。
参数:
K 键空间事件,以__keyspace@
__为前缀发布消息
E 键事件事件,以__keyevent@__为前缀发布消息
g 通用命令(非特定类型),例如 DEL、 EXPIRE、 RENAME等
$ 字符串命令
l 列表命令
s 集合命令
h 哈希命令
z 有序集合命令
x 键过期事件(每次当一个键过期时生成的事件)
e 键淘汰事件(当一个键由于内存超量导致被淘汰时生成的事件)
A 参数g$lshzxe的别名,因此"AKE"字符串表示所有的事件
K或E至少有一个应该出现在参数字符串中,否则,无论字符串的其他部分是什么,都不会推送事件。 例如,为了只针对列表开启键-空间事件,配置参数必须设置为Kl,以此类推。 字符串KEA可以用来开启任何可能的事件。
事件列表
DEL 命令会对每一个被删除的键生成一个del event。
RENAME 命令会生成两个事件,对源键生成一个rename_from事件,对目标键生成一个rename_to事件。
EXPIRE 命令在对一个键设置过期时间时生成一个expire event,或在每次使用正数时间对一个键设置过期时间后导致键因过期被删除时生成一个expired event(查看EXPIRE的文档来获取更多信息)。
SORT 命令在使用STORE设置一个新建时会生成一个sortstore event。如果结果列表为空,并使用了STORE选项,且相同的键名已经存在,结果就是这个键被删除,因此这种情况下会生成一个del event。
SET和它的左右变种(SETEX、SETNX、GETSET)会生成set events。然而SETEX同时还会生成一个expire events。
MSET 会对每个键生成一个独立的set event。
SETRANGE 命令生成一个setrange event。
INCR、DECR、INCRBY、DECRBY 命令都会生成incrby events。
INCRBYFLOAT 命令会生成一个incrbyfloat events。
APPEND 命令会生成一个append event。
LPUSH和LPUSHX 命令会生成一个单一的lpush event,即使是在复杂情况下。
RPUSH和RPUSHX 命令会生成一个单一的rpush event,即使是在复杂情况下。
RPOP 命令会生成一个rpop event。如果列表中的最后一个元素被弹出,还会额外生成一个del event。
LPOP 命令会生成一个lpop event。如果列表中的第一个元素被弹出,还会额外生成一个del event。
LINSERT 命令会生成一个linsert event。
LSET 命令会生成一个lset event。
LREM 命令会生成一个lrem event,如果结果列表为空且键被删除将额外生成一个del event。
LTRIM 命令会生成一个ltrim event,如果结果列表为空且键被删除将额外生成一个del event。
RPOPLPUSH和BRPOPLPUSH 命令会生成一个rpop event和一个lpush event。在这两种情况下,顺序都是有保证的(lpush event将总是在rpop event之后被推送)。如果结果列表长度为0且键被删除将额外生成一个del event。
HSET、HSETNX和HMSET 都会生成一个单一的hset event。
HINCRBY 命令会生成一个hincrby event。
HINCRBYFLOAT 命令会生成一个hincrbyfloat event。
HDEL 命令会生成一个单一的hdel event,如果结果哈希为空且键被删除将额外生成一个del event。
SADD 命令会生成一个单一的sadd event,即使是在复杂情况下。
SREM 命令会生成一个单一的srem event,如果结果集合为空且键被删除将额外生成一个del event。
SMOVE 命令会对源键生成一个srem event,且对目标键生成一个sadd event。
SPOP 命令会生成一个spop event,如果结果集合为空且键被删除将额外生成一个del event。
SINTERSTORE、SUNIONSTORE、SDIFFSTORE 会分别生成sinterstore event、sunionostore event、sdiffstore event。在集合为空且被存储的键已经存在的特殊情况下,由于key会被删除会生成一个del event。
ZINCR 命令会生成一个zincr event。
ZADD 命令会生成一个单一的zadd event,即使有多个元素一次性被添加。
ZREM 命令会生成一个的那一的zrem event,即使有多个元素一次性被删除。当结果有序集合为空且键被删除,会生成一个额外的del event。
ZREMBYSCORE 命令会生成一个单一的zrembyscore event。当结果有序集合为空且键被删除,会生成一个额外的del event。
ZREMBYRANK 命令会生成一个单一的zrembyrank event。当结果有序集合为空且键被删除,会生成一个额外的del event。
ZINTERSTORE和ZUNIONSTORE 会分别生成zinterstore event和zunionstore event。在有序集合为空且被存储的键已经存在的特殊情况下,由于key会被删除会生成一个del event。
每次由于键的过期时间到导致键被从数据集中删除时,会生成一个expired event。
每次由于Redis超过最大内存限制 ,使用maxmemory policy释放内存导致一个键从数据集中被淘汰时,会生成一个evicted event。
** 只有在目标键真正被修改时,所有命令才会生成事件。例如一个SREM命令从一个集合中删除了一个不存在的元素,这实际上不会对键造成改变,因此不会生成任何事件。 **
测试用例:
redis-cli config set notify-keyspace-events KA
redis-cli psubscribe '__keyspace*'
过期事件
有生存时间的键在Redis中过期有两种方式:
当键被一个命令访问且发现键已过期。
通过在后台系统中运行定时任务增量地查找过期键,这样能够收集到那些从未被访问键。
当一个键被访问且被上述两种方法之一发现已过期时会生成expired events,这就会导致一个结果,Redis服务器将无法保证在键的生存时间变为0时立即生成expired events。
如果没有命令不断地访问键,且有很多的键被设置了生存时间,则在键的生存时间下降到0和生成expired events这之间会有一个显著的延迟。
基本上来说,Redis服务器是在删除过期键时,而不是在键的生存时间理论上变为0时生成expired events。