Redis发布与订阅操作
2020-07-18 04:31
211 查看
文章目录
引言
Redis支持频道订阅和模式订阅;
- 频道订阅:订阅的频道和发布消息的频道相同时,客户端可以接收到消息,如一个客户端订阅频道
news.it
,则只有频道news.it
的消息才可以发送给该客户端; - 模式订阅:一个模式可以匹配一个或多个频道,当发布消息的频道与订阅的频道模式匹配时,客户端可以接收到消息,如一个客户端订阅模式
news.[ie]t
,则它可以接收发布到频道news.it
和news.et
的消息;
1. 数据结构
1.1 频道字典
- 用于频道订阅;
- 多个客户端可以订阅相同的频道,在服务器的
redisServer
结构里有一个pubsub_channels
属性,是一个字典,维护了所有被订阅的频道; - 字典的键是被订阅的频道,字典的值则是一个链表,链表里记录了所有订阅这个频道的客户端;
struct redisServer{ // ... // 保存所有频道的订阅关系 dict *pubsub_channels; // ... };
2. 模式链表
- 用于模式订阅;
- 一个模式可以匹配一个或多个频道;每个客户端订阅的模式可能各不相同,所以将客户端和订阅的模式构建成一个
pubsubPattern
结构,然后将多个订阅构成一张链表,存放在redisServer
的pubsub_patterns
属性里;
struct redisServer{ // ... // 保存所有模式订阅关系 list *pubsub_patterns; // ... }; typedef struct pubsub_pattern{ // 订阅模式的客户端 redisClient *client; // 被订阅的模式 robj *pattern; }pubsub_pattern;
2. 发布订阅命令
2.1 订阅频道命令 subscribe
# 订阅频道 "news.sport" 和 "news.movie" SUBSCRIBE "news.sport" "news.movie"
每当客户端执行
SUBSCRIBE命令订阅某个或某些频道时,服务器都会将客户端与被订阅的频道在
pubsub_channels字典中进行关联:
- 如果频道已经有其他订阅者(字典中已经存在键为当前频道的订阅者链表),那么服务端直接将客户端添加到订阅者链表的末尾;
- 如果频道还未有任何订阅者(字典中没有存在键为当前频道的订阅者链表),服务器首先在
pubsub_channels
字典中为频道创建一个键,并将这个键的值设置为空链表,然后再将客户端添加到链表,成为链表的第一个元素;
2.2 退订频道 unscubscribe
# 退订频道 "news.sport" 和 "news.movie" UNSUBSCRIBE "news.sport" "news.movie"
当一个客户端退订某个频道或者某些频道时,服务器将从
pubsub_channels字典中解除客户端与频道之间的关联:
- 程序会根据根据退订的频道名字,在
pubsub_channels
字典中找到频道对应的订阅者链表,然后从订阅者链表中删除退订客户端的信息; - 如果删除退订客户端之后,频道的订阅者链表变成了空链表,那么说明这个频道已经没有任何订阅者了,程序将从
pubsub_channels
字典中删除频道对应的键;
2.3 订阅模式 psubscribe
# 订阅所有以 "news."开头的频道 PSUBSCRIBE "news.*"
订阅模式是服务器端的
pubsub_patterns链表中添加节点;
每到客户端执行
PSUBSCRIBE命令订阅某个或某些模式时,服务器会对每个被订阅的模式执行以下两个操作:
- 新建一个
pubsubPattern
结构,将结构的pattern
属性设置为被订阅的模式,client
属性设置为订阅该模式的客户端; - 将
pubsubPattern
结构添加到pubsub_patterns
链表的末尾;
2.4 退订模式 punsubscribe
# 退订模式 "news.*" PUNSUBSCRIBE "news.*"
当一个客户端退订某个或某些模式的时候,服务器将在
pubsub_patterns链表中查找并删除那些
pattern属性为被退订模式,并且
client属性为执行退订命令的客户端的
pubsubPattern结构
2.5 发送消息 publish
PUBLISH <channel> <message> # 向频道 "news.it"发送 "hello"消息 PUBLISH "news.it" "hello"
当一个客户端执行
PUBLISH命令将消息
message发送给频道
channel时,服务器需要执行以下两个操作:
- 查询
pubsub_channels
字典,将消息发送给channel
频道的所有订阅者; - 遍历
pubsub_patterns
链表,如果某个订阅模式pattern
与频道channel
相匹配,那么将消息发送给pattern
模式的订阅者;
注意:
- 发送消息只有一个命令
PUBLISH
; PUBLISH
可以同时将消息发送给频道订阅者和模式订阅者;
参考文献
- 《Redis设计与实现》黄建宏 著,机械工业出版社.
相关文章推荐
- 使用jedis操作redis之消息的发布和订阅
- Spring RedisTemplate操作-发布订阅操作(8)
- Python操作Redis之订阅与发布
- Spring RedisTemplate操作-发布订阅操作(8)
- Python操作redis的订阅发布功能
- (二)Redis 笔记——发布&订阅、事务、数据库操作
- redis操作订阅和发布
- Python redis操作实例分析【连接、管道、发布和订阅等】
- redis 学习手册之发布和订阅pubsub操作
- redis订阅发布消息操作本地缓存
- python操作redis进行发布和订阅消息
- spring整合redis发布订阅操作
- Redis学习笔记(九) 命令进阶:Pub/Sub(发布/订阅)操作
- Redis五大类型操作使用以及订阅发布功能
- redis基础简介(四)- 消息的发布订阅
- redis发布、订阅
- redis实现发布订阅
- Redis的消息订阅与发布
- Redis 订阅与发布
- StackExchange.Redis官方文档(六)【事件,发布订阅,服务器命令】