Redis数据库的通知机制

534 阅读2分钟

这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

Redis数据库的通知机制

发送通知

某个键执行了什么命令的通知为键空间通知,某个命令被哪个键执行了是键事件通知。

发送数据库的通知由notify.c 的notifyKeyspaceEvent 实现

通知类型通过notify-keyspace-events属性来配置:

发送所有类型的键空间通知和键事件通知,设置值AKE

发送所有类型的键空间通知,设置值AK

发送所有类型的键事件通知,设置值AE

只发送和字符串键有关的键空间,设置值K$

只发送和列表键有关的键事件通知,可以将选项的值设置为El

void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) {
    sds chan;
    robj *chanobj, *eventobj;
    int len = -1;
    char buf[24];

    /* If any modules are interested in events, notify the module system now.
     * This bypasses the notifications configuration, but the module engine
     * will only call event subscribers if the event type matches the types
     * they are interested in. */
     moduleNotifyKeyspaceEvent(type, event, key, dbid);

    /* If notifications for this class of events are off, return ASAP. */
    if (!(server.notify_keyspace_events & type)) return;

    eventobj = createStringObject(event,strlen(event));

    /* __keyspace@<db>__:<key> <event> notifications. */
    if (server.notify_keyspace_events & NOTIFY_KEYSPACE) {
        chan = sdsnewlen("__keyspace@",11);
        len = ll2string(buf,sizeof(buf),dbid);
        chan = sdscatlen(chan, buf, len);
        chan = sdscatlen(chan, "__:", 3);
        chan = sdscatsds(chan, key->ptr);
        chanobj = createObject(OBJ_STRING, chan);
        pubsubPublishMessage(chanobj, eventobj);
        decrRefCount(chanobj);
    }

    /* __keyevent@<db>__:<event> <key> notifications. */
    if (server.notify_keyspace_events & NOTIFY_KEYEVENT) {
        chan = sdsnewlen("__keyevent@",11);
        if (len == -1) len = ll2string(buf,sizeof(buf),dbid);
        chan = sdscatlen(chan, buf, len);
        chan = sdscatlen(chan, "__:", 3);
        chan = sdscatsds(chan, eventobj->ptr);
        chanobj = createObject(OBJ_STRING, chan);
        pubsubPublishMessage(chanobj, key);
        decrRefCount(chanobj);
    }
    decrRefCount(eventobj);
}

type 为当前发送的通知类型,event 是事件名称,key 为产生事件的键,dbid 是产生事件的数据库号码

根据这几个参数构建事件通知的内容,已经接收通知的频道

  1. server.notify_keyspace_events 为服务器配置的notify-keyspace-events 属性值,如果给定的通知类型type 不是服务器允许发送的通知类型,函数直接返回
  2. 如果给定的通知是服务器允许发送的通知,判断服务器是否允许发送键空间通知,如果允许,程序构建和发送事件通知
  3. 判断是否允许发送键事件通知,如果允许,发送事件通知