Redis 订阅发布模式(pub/sub)浅析

Redis 支持简单的 pub/sub 功能,之所以说其简单,是因为消息是发送即遗忘的(fire and forgot),不会进行持久化,一旦宕机,消息丢失。

客户端可以使用两种方式订阅消息:

  • 频道(channel)
  • 模式(pattern)

频道是最简单和核心的方式,模式是基于频道的模式匹配。例如:现有频道 "it.news" 和 "it.post" ,客户端可以直接订阅 "it.new",或者可以订阅模式 "it.*" 从而在频道 "it.news" 和 "it.post"有消息时得到通知。

深入 Redis 源代码(branch: 6.0)来探究 Redis pub/sub 功能的实现。

在 redisServer 和 client 中包含了 pubsub_channels 和 pubsub_patterns,如下(server.h):

struct redisServer {
  dict *pubsub_channels;
  list *pubsub_patterns;
  dict *pubsub_patterns_dict;
  // ...
}
typedef struct client {
   dict *pubsub_channels;
   list *pubsub_patterns;
  // ...
} client;

typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;
typedef struct dictht {
    dictEntry **table;
  	// ...
} dictht;
typedef struct dict {
    dictType *type;
    dictht ht[2];
  	// ...
} dict;

typedef struct list {
    listNode *head;
    listNode *tail;
    unsigned long len;
  	// ...
} list;
typedef struct pubsubPattern{
  client *client;
  robj *pattern;
} pubsubPattern;

pubsub_channels 是字典类型(见 dict.c),内部实现是哈希表(hash table),键为 channel,值为订阅该频道的客户端列表 clients。

pubsub_patterns 是一个列表类型(见 adlist.h),内部实现是双向链表,元素为 pubsubPattern,pubsubPattern 包含 glob匹配模式(通配符匹配模式,广泛运用于 Linux 中的 ls、find、mv 等等命令,git 中的 .gitignore 文件中) pattern 和订阅了该匹配模式客户端 client。

posted @ 2022-04-12 15:17  東籬老農  阅读(164)  评论(0编辑  收藏  举报