源码位置:notify.c/server.h
1. 事件通知概述
对于Redis服务器,它可以通过订阅发布功能来发送服务器中的键空间事件。所谓的键空间事件,就是数据库中键的增加、修改和删除等操作,用于告知收听该类事件的客户端当前数据库中执行了哪些操作。客户端可以通过 订阅与发布功能(pub/sub)功能,来接收那些以某种方式改动了Redis数据集的事件。
目前Redis的订阅与发布功能采用的是发送即忘(fire and forget)的策略,当订阅事件的客户端断线时,它会丢失所有在断线期间分发给它的事件。
订阅与发布功能(pub/sub)功能实现在pubsub.c中,后续会在博文中讲到。
2. 事件类型
对于每个修改数据库的操作,键空间通知都会发送两种不同类型的事件:
- 键空间通知(key-space)
- 键事件通知(key-event)
当 del mykey
命令执行时:
- 键空间频道的订阅者将接收到被执行的事件的名字,在这个例子中,就是 del
- 键事件频道的订阅者将接收到被执行事件的键的名字,在这个例子中,就是 mykey
3. 配置
因为开启键空间通知功能需要消耗一些 CPU,所以在默认配置下,该功能处于关闭状态。开启通知功能有以下两种方式:
- 修改 redis.conf 中的
notify-keyspace-events
参数 - 通过 CONFIG SET 命令来设定
notify-keyspace-events
参数
notify-keyspace-events
参数可以是以下字符的任意组合, 它指定了服务器该发送哪些类型的通知:
字符 | 发送的通知 |
---|---|
K | 键空间通知,所有通知以 keyspace@\ |
E | 键事件通知,所有通知以 keyevent@\ |
g | DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知 |
$ | 字符串命令的通知 |
l | 列表命令的通知 |
s | 集合命令的通知 |
h | 哈希命令的通知 |
z | 有序集合命令的通知 |
x | 过期事件:每当有过期键被删除时发送 |
e | 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送 |
A | 参数 g$lshzxe 的别名,包含所有的字符 |
输入的参数中至少要有一个 K 或者 E,否则的话,不管其余的参数是什么,都不会有任何通知被分发。
在源码中设定了一系列的宏定义,用来标识以上这些字符事件的类型:
1 | // 键空间通知的类型,每个类型都关联着一个有目的的字符 |
在notify.c文件中,只有三个功能函数,下面让我们来看看源码实现吧。
函数功能总览
1 | /* Keyspace events notification */ |
主要函数实现
1 | /* 因为redis命令中事件类型是字符类型,所以会使用一个int类型的flags参数 |
1 | // 将flags参数转为sds类型 |
1 | // 利用Redis的订阅和发布功能来发送键空间事件通知。 |