欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis 数据库通知功能的实现

程序员文章站 2022-05-13 12:53:03
...
        Reids 数据库通知功能可以让客户端通过订阅给定的频道或者模式,来获知数据库中键的变化,以及数据库中命令的执行情况。
        比如,以下代码展示了客户端如何获取 0 号数据库中针对 message 键执行的所有命令。
redis> SUBSCRIBE __keyspace@0__:message
Reading messages... (press Ctrl-C to quit)

1) "subscribe"                  // 订阅信息
2) "__keyspace@0__:message"
3) (integer) 1

1) "message"                    // 执行 SET 命令
2) "__keyspace@0__:message"
3) "set"

1) "message"                    // 执行 EXPIRE 命令
2) "__keyspace@0__:message"
3) "expire"

        根据发回的通知显示,可见先后共有 SET 和 EXPIRE 两个命令对键 message 进行了操作。
        像这一类关注“某个键执行了什么命令”的通知称为键空间通知(key-space notification),此外,还有另一类称为键事件通知(key-event notification),它们关注的是“某个命令被什么键执行了”。以下代码就是客户端如何获取 0 号数据库中所有执行了 DEL 命令的键的键事件通知的例子。
redis> SUBSCRIBE __keyevent@0__:del
Reading messages... (press Ctrl-C to quit)

1) "subscribe"                 // 订阅信息
2) "__keyevent@0__:del"
3) (integer) 1

1) "message"                   // 键 key 执行了 DEL 命令
2) "__keyevent@0__:del"
3) "key"

1) "message"                   // 键 number 执行了 DEL 命令
2) "__keyevent@0__:del"
3) "number"

        服务器的 notify-keyspace-events 配置选项值决定了服务器所发送通知的类型,如(更多设置可参考 Redis 的官方文档说明):
        (1)值 AKE 表示想让服务器发送所有类型的键空间通知和键事件通知。
        (2)值 AK 表示想让服务器发送所有类型的键空间通知。
        (3)值 AE 表示想让服务器发送所有类型的键事件通知。
        (4)值 KS 表示想让服务器只发送和字符串键有关的键空间通知。
        (5)值 EL 表示想让服务器只发送和列表键有关的键事件通知。
        发送数据库通知的功能是由 notifyKeyspaceEvent 函数实现的,其伪代码实现如下。
def notifyKeyspaceEvent(type, event, key, dbid):
    # 如果给定的通知不是服务器配置允许发送的通知,则直接返回
    if not (server.notify_keyspace_events & type):
        return
    # 发送键空间通知
    if server.notify_keyspace_events & REDIS_NOTIFY_KEYSPACE:
        # 将通知发送给频道“__keyspace@<dbid>__:<key>”
        # 内容为键所发生的事件 <event>
        # 构建频道名字
        chan = "__keyspace@{dbid}__:{key}".format(dbid=dbid, key=key)
        # 发送通知
        pubsubPublishMessage(chan, event)

    # 发送键事件通知
    if server.notify_keyspace_events & REDIS_NOTIFY_KEYEVENT:
        # 将通知发送给频道“__keyevent@<dbid>__:<event>”
        # 内容为发生事件的键 <key>
        # 构建频道名字
        chan = "__keyevent@{dbid}__:{event}".format(dbid=dbid, event=event)
        # 发送通知
        pubsubPublishMessage(chan, key)

        其中的 pubsubPublishMessage 函数就是 PUBLISH 命令的实现函数,订阅数据库通知的客户端收到的信息就是由这个函数发出的,其具体实现细节留待后面再进行介绍。


参考书籍:《Redis 设计与实现》第 9 章——数据库。