redis消息订阅

发布订阅模式

发布订阅模式(pubsub pattern)中,消息发布者(publisher)发布消息(message)到一个频道(channel/topic),订阅者(subscriber)订阅其中的频道。当发布者发布消息到一个频道时,所有的订阅这个频道的订阅者都会收到这个消息。

发布消息
发布消息
订阅消息
订阅消息
订阅消息
消息发布者1
频道channel
消息发布者2
订阅者subscriber1
收到消息
订阅者subscriber3
收到消息
订阅者subscriber2
收到消息

生产者/消费者模式

生产消费模式和发布订阅的不同之处在于,消息只能被一个消费者消费。

生产消息
生产消息
抢夺消息
抢夺消息
抢夺消息
消息生产者1
频道channel
消息生产者2
消息消费者1
消费消息
消息消费者3
消息消费者2

例子

  1. 客户端1发布消息:
127.0.0.1:6379> publish info hello		//向info频道发送消息
(integer) 1								//返回订阅info频道的订阅者的数量 
127.0.0.1:6379> publish info hi
(integer) 1
127.0.0.1:6379> 
  1. 客户端2订阅频道:
127.0.0.1:6379> subscribe info					//订阅频道info
Reading messages... (press Ctrl-C to quit)
1) "subscribe"									//订阅频道返回的消息,表示订阅成功,消息又三部分组成,第一是“subscribe”字符串,表示这是一个订阅消息,第二是定于频道的名字,第三是当前订阅频道数量
2) "info"										
3) (integer) 1
1) "message"									//消息发布者的消息,消息由三部分组成,第一是“message”字符串,表示这是一个消息,第二是定于频道的名字,第三是消息内容
2) "info"
3) "hello"
1) "message"
2) "info"
3) "hi

命令

命令解析
publish channel message发布消息到指定频道
subscribe channel [channel...]订阅一或者多个频道
psubscribe pattern [pattern...]模式订阅,pattern是一个正则表达式,称之为模式,利用这个正则可以订阅与之匹配的频道
unsubscribe channel [channel...]取消订阅
punsubscribe pattern [pattern...]取消模式订阅
pubsub <subcommand> [argument [argument...]]自检命令,用来检查发布订阅的状态,如当前有多少频道,频道下有多少订阅者

两种订阅方式:频道订阅和模式订阅

消息的订阅有两种方式,一种是订阅频道(看例子章节),另一种是订阅一个模式(正则),如果一个消息的频道名字和这个模式匹配,这个消息就会发送给订阅了这个模式的订阅者。

  1. 客户端1向info和information两个频道发送消息:
127.0.0.1:6379> publish info 'how are you'
(integer) 2
127.0.0.1:6379> publish information 'im information channel!!'
(integer) 1
127.0.0.1:6379> 
  1. 客户端2向redis服务器订阅了inf*这个模式:
127.0.0.1:6379> 
127.0.0.1:6379> psubscribe inf*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"									//psubscribe消息,表示订阅成功
2) "inf*"										//模式订阅
3) (integer) 1									//当前只订阅了一个模式
1) "pmessage"									//pmessage表示这是一个普通消息
2) "inf*"										//消息对应的pattern
3) "info"										//那个频道发送过来的,显然info匹配inf*这个正则表达式
4) "how are you"								//消息内容
1) "pmessage"
2) "inf*"
3) "information"
4) "im information channel!!"

如果订阅者订阅了多个模式,一个消息的频道与几个模式都匹配的话,订阅者就会收到多个消息。

127.0.0.1:6379> psubscribe i*f in* *for*		//同时订阅三个模式
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "i*f"
3) (integer) 1
1) "psubscribe"
2) "in*"
3) (integer) 2
1) "psubscribe"
2) "*for*"
3) (integer) 3								  //总共订阅三个模式
1) "pmessage"								  //消息A
2) "*for*"
3) "information"
4) "hello"
1) "pmessage"								  //消息A,一个消息收到了两次
2) "in*"
3) "information"
4) "hello"

订阅关系的底层实现

以下是redis源码server.h中声明的保存订阅关系的变量,从中不难看出,用subscrib命令订阅的关系放在字典,而模式订阅放在一个列表中。

    dict *pubsub_channels;  /* channels a client is interested in (SUBSCRIBE) */
    list *pubsub_patterns;  /* patterns a client is interested in (SUBSCRIBE) */

redis中使用subscribe命令订阅频道,客户端与频道的订阅关系被保存在一个名为pubsub_channels的字典里面。当有客户端订阅频道时,会将对应的信息保存到字典的对应的链表中。取消订阅时,redis会将对应的键值对从字典中删除。当发布消息时,将channel哈希定位到具体的链表,给里面对应的客户端发送消息。

模式订阅中订阅关系保存在一个字典中
模式订阅的订阅关系被保存在一个链表中,链表中的每个结点都是一个pubsubPattern结构体

typedef struct pubsubPattern {
    client *client;
    robj *pattern;
} pubsubPattern;

pubsubPattern

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值