【Redis】键空间通知

本文详细介绍了Redis的键空间通知功能,包括如何通过订阅频道获取数据变动事件,事件的类型如键空间和键事件通知,以及配置和命令产生的通知。通过实例展示了如何设置和测试通知,强调了通知的可靠性和过期键的处理机制。
摘要由CSDN通过智能技术生成

1. 功能概览

键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种方式改动了 Redis 数据集的事件。

以下是一些键空间通知发送的事件的例子:

  • 所有修改键的命令。

  • 所有接收到 LPUSH key value [value …] 命令的键。

  • 0 号数据库中所有已过期的键。

事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发, 因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下, 直接使用键空间通知功能。

因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果你的程序需要可靠事件通知(reliable notification of events), 那么目前的键空间通知可能并不适合你: 当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件

2. 事件的类型

对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件。

比如说,对 0 号数据库的键 mykey 执行 DEL key [key …]命令时, 系统将分发两条消息, 相当于执行以下两个命令:

PUBLISH __keyspace@0__:mykey del
PUBLISH __keyevent@0__:del mykey

订阅第一个频道 __keyspace@0__:mykey 可以接收 0 号数据库中所有修改键 mykey 的事件, 而订阅第二个频道 __keyevent@0__:del 则可以接收 0 号数据库中所有执行 del 命令的键。

以 keyspace 为前缀的频道被称为键空间通知(key-space notification),

以 keyevent 为前缀的频道则被称为键事件通知(key-event notification)。

当 del mykey 命令执行时:

  • 键空间频道的订阅者将接收到被执行的事件的名字,在这个例子中,就是 del 

  • 键事件频道的订阅者将接收到被执行事件的键的名字,在这个例子中,就是 mykey 

3. 配置

因为开启键空间通知功能需要消耗一些 CPU , 所以在默认配置下, 该功能处于关闭状态。

可以通过修改 redis.conf 文件, 或者直接使用 CONFIG SET 命令来开启或关闭键空间通知功能:

  • 当 notify-keyspace-events 选项的参数为空字符串时,功能关闭。

  • 另一方面,当参数不是空字符串时,功能开启。

notify-keyspace-events 的参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:

字符

发送的通知

K

键空间通知,所有通知以 __keyspace@<db>__ 为前缀

E

键事件通知,所有通知以 __keyevent@<db>__ 为前缀

g

DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知

$

字符串命令的通知

l

列表命令的通知

s

集合命令的通知

h

哈希命令的通知

z

有序集合命令的通知

x

过期事件:每当有过期键被删除时发送

e

驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送

A

参数 g$lshzxe 的别名

输入的参数中至少要有一个 K 或者 E , 否则的话, 不管其余的参数是什么, 都不会有任何通知被分发。

举个例子, 如果只想订阅键空间中和列表相关的通知, 那么参数就应该设为 Kl , 诸如此类。

将参数设为字符串 "KEA" 表示发送所有类型的通知。

4. 命令产生的通知

不同命令所产生的不同通知
命令说明
DEL key [key …]命令为每个被删除的键产生一个 del 通知
RENAME key newkey

产生两个通知:

来源键(source key)产生一个 rename_from 通知,

目标键(destination key)产生一个 rename_to 通知

EXPIRE key seconds 

EXPIREAT key timestamp

在键被正确设置过期时间时产生一个 expire 通知

当 EXPIREAT key timestamp 设置的时间已经过期,或者 EXPIRE key seconds 传入的时间为负数值时,键被删除,并产生一个 del 通知

SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern …]] [ASC | DESC] [ALPHA] [STORE destination]在命令带有 STORE 参数时产生一个 sortstore 事件。如果 STORE 指示的用于保存排序结果的键已经存在,那么程序还会发送一个 del 事件

SET key value [EX seconds] [PX milliseconds] [NX|XX]

以及它的所有变种(SETEX  SETNX  和 GETSET )

都产生 set 通知。其中 SETEX key seconds value 还会产生 expire 通知
MSET key value [key value …]为每个键产生一个 set 通知
SETRANGE key offset value产生一个 setrange 通知
INCR key 、 DECR key 、 INCRBY key increment 和 DECRBY key decrement产生 incrby 通知
INCRBYFLOAT key increment产生 incrbyfloat 通知
APPEND key value产生 append 通知
LPUSH key value [value …]  LPUSHX key value都产生单个 lpush 通知,即使有多个输入元素时,也是如此
RPUSH key value [value …]  RPUSHX key value都产生单个 rpush 通知,即使有多个输入元素时,也是如此
RPOP key产生 rpop 通知。如果被弹出的元素是列表的最后一个元素,那么还会产生一个 del 通知
LPOP key产生 lpop 通知。如果被弹出的元素是列表的最后一个元素,那么还会产生一个 del 通知
LINSERT key BEFORE|AFTER pivot value产生一个 linsert 通知
LSET key index value产生一个 lset 通知
LTRIM key start stop产生一个 ltrim 通知。如果 LTRIM key start stop 执行之后,列表键被清空,那么还会产生一个 del 通知
RPOPLPUSH source destination 和 BRPOPLPUSH source destination timeout产生一个 rpop 通知,以及一个 lpush 通知。两个命令都会保证 rpop 的通知在 lpush 的通知之前分发。如果从键弹出元素之后,被弹出的列表键被清空,那么还会产生一个 del 通知
HSET hash field value 、 HSETNX hash field value 和 HMSET都只产生一个 hset 通知
HINCRBY产生一个 hincrby 通知
HINCRBYFLOAT产生一个 hincrbyfloat 通知
HDEL产生一个 hdel 通知。如果执行 HDEL 之后,哈希键被清空,那么还会产生一个 del 通知
SADD key member [member …]产生一个 sadd 通知,即使有多个输入元素时,也是如此
SREM key member [member …]产生一个 srem 通知,如果执行 SREM key member [member …] 之后,集合键被清空,那么还会产生一个 del 通知
SMOVE source destination member为来源键(source key)产生一个 srem 通知,并为目标键(destination key)产生一个 sadd 事件
SPOP key产生一个 spop 事件。如果执行 SPOP key 之后,集合键被清空,那么还会产生一个 del 通知
SINTERSTORE destination key [key …]  产生 sinterstore通知。如果用于保存结果的键已经存在,那么还会产生一个 del 通知
SUNIONSTORE destination key [key …]产生 sunionostore通知。如果用于保存结果的键已经存在,那么还会产生一个 del 通知
SDIFFSTORE destination key [key …]产生 sdiffstore通知。如果用于保存结果的键已经存在,那么还会产生一个 del 通知
ZINCRBY key increment member产生一个 zincr 通知
ZADD key score member [[score member] [score member] …]产生一个 zadd 通知,即使有多个输入元素时,也是如此
ZREM key member [member …]

产生一个 zrem 通知,即使有多个输入元素时,也是如此。

如果执行 ZREM key member [member …] 之后,有序集合键被清空,那么还会产生一个 del 通知

ZREMRANGEBYSCORE key min max

产生一个 zrembyscore 通知。

如果用于保存结果的键已经存在,那么还会产生一个 del 通知

ZREMRANGEBYRANK key start stop

产生一个 zrembyrank 通知。

如果用于保存结果的键已经存在,那么还会产生一个 del 通知

一个键因为过期而被删除时产生一个 expired 通知
一个键因为 maxmemory 策略而被删除时产生一个 evicted 通知

🎈注意:

所有命令都只在键真的被改动了之后,才会产生通知。

比如说,当 SREM key member [member …] 试图删除不存在于集合的元素时,删除操作会执行失败,因为没有真正的改动键,所以这一操作不会发送通知。

🎈Redis 使用以下两种方式删除过期的键:

  • 当一个键被访问时,程序会对这个键进行检查,如果键已经过期,那么该键将被删除。

  • 底层系统会在后台渐进地查找并删除那些过期的键,从而处理那些已经过期、但是不会被访问到的键。

当过期键被以上两个程序的任意一个发现、 并且将键从数据库中删除时, Redis 会产生一个 expired 通知。

Redis 并不保证生存时间(TTL)变为 0 的键会立即被删除: 如果程序没有访问这个过期键, 或者带有生存时间的键非常多的话, 那么在键的生存时间变为 0 , 直到键真正被删除这中间, 可能会有一段比较显著的时间间隔。

因此, Redis 产生 expired 通知的时间为过期键被删除的时候, 而不是键的生存时间变为 0 的时候。

5. 实例

如果对命令所产生的通知有疑问, 最好还是使用以下命令, 自己来验证一下:

启动一个消费客户端, 设置config set notify-keyspace-events KEA开启键空间通知,发送所有类型的通知。

❯ .\redis-cli.exe -h 127.0.0.1
127.0.0.1:6379> config set notify-keyspace-events KEA
OK
127.0.0.1:6379> psubscribe '__key*__:*'
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "__key*__:*"
3) (integer) 1

使用另一个连接出发redis 数据变更事件

❯ .\redis-cli.exe -h 127.0.0.1
127.0.0.1:6379> set dog woohoo
OK
127.0.0.1:6379> get dog
"woohoo"
127.0.0.1:6379> rename dog doge
OK
127.0.0.1:6379> set dog bage
OK
127.0.0.1:6379> rename dog doge
OK
127.0.0.1:6379> del doge
(integer) 1

查看消费者收到的通知

# set dog woohoo
1) "pmessage"
2) "__key*__:*"
3) "__keyspace@0__:dog"
4) "set"
1) "pmessage"
2) "__key*__:*"
3) "__keyevent@0__:set"
4) "dog"

# rename dog doge
1) "pmessage"
2) "__key*__:*"
3) "__keyspace@0__:dog"
4) "rename_from"
1) "pmessage"
2) "__key*__:*"
3) "__keyevent@0__:rename_from"
4) "dog"
1) "pmessage"
2) "__key*__:*"
3) "__keyspace@0__:doge"
4) "rename_to"
1) "pmessage"
2) "__key*__:*"
3) "__keyevent@0__:rename_to"
4) "doge"

# del doge
1) "pmessage"
2) "__key*__:*"
3) "__keyspace@0__:doge"
4) "del"
1) "pmessage"
2) "__key*__:*"
3) "__keyevent@0__:del"
4) "doge"

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值