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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章