#yyds干货盘点# redis | 十七redis之订阅发布

Posted anyoneElse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点# redis | 十七redis之订阅发布相关的知识,希望对你有一定的参考价值。


公众号:雨中散步撒哈拉

文章同步公众号,共同学习进步

个人网站:​​ https://liudongdong.top​​​

文章来源:​​ https://liudongdong.top/archives/redisshi-qi-redis-zhi-ding-yue-fa-bu​


一、概念

1. 订阅发布组件

发布订阅是一种消息通信模式,分为消息发送者 ( pub ) 和消息订阅者 ( sub ) 发布订阅模式的核心是一种 FIFO 的队列

#yyds干货盘点#

发布订阅模式中有三个角色

  1. 发布者
  2. 队列,在 Redis 中称为频道
  3. 订阅者

发布者将消息推送到队列中,订阅者再从队列中拉取消息。 发送者无须知道任何关于订阅者的信息, 而订阅者也无须知道是那个客户端给它发送信息, 它只要关注自己感兴趣的频道即可。 对发布者和订阅者进行解构(decoupling), 可以极大地提高系统的扩展性(scalability), 并得到一个更动态的网络拓扑(network topology)。

2. 订阅发布原理

通过 SUBSCRIBE 命令订阅某频道后,redis-server 中维护了一个字典,字典的键就是一个个 channel ( 频道 ),而字典的值则是一个链表,链表中保存了所有订阅这个频道的客户端,SUBSCRIBE 命令的关键是将客户端添加到指定频道的订阅链表中 通过 PUBLISH 命令可以向订阅者发送消息,redis-server 会使用给定的频道作为 key,遍历其对应的客户端链表,将消息发送给所有的订阅者

二、订阅发布流程

redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

#yyds干货盘点#

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

#yyds干货盘点#

三、订阅发布测试实例

1. 客户端1订阅频道

Redis Subscribe 命令用于订阅给定的一个或多个频道的信息。。 ​​redis 127.0.0.1:6379> SUBSCRIBE channel [channel ...]​​ 实例:

127.0.0.1:6379> subscribe first second
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "first"
3) (integer) 1
1) "subscribe"
2) "second"
3) (integer) 2

2. 客户端2,first频道发布消息

Redis Publish 命令用于将信息发送到指定的频道。 ​​redis 127.0.0.1:6379> PUBLISH channel message​​ 实例:

127.0.0.1:6379> publish first first_msg
(integer) 1
127.0.0.1:6379>

3. 客户端3,second频道发布消息

Redis Publish 命令用于将信息发送到指定的频道。 ​​redis 127.0.0.1:6379> PUBLISH channel message​​ 实例:

127.0.0.1:6379> publish second second_msg
(integer) 1
127.0.0.1:6379>

4. 查看客户端1详细信息

127.0.0.1:6379> subscribe first second
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "first"
3) (integer) 1
1) "subscribe"
2) "second"
3) (integer) 2
1) "message"
2) "first"
3) "first_msg"
1) "message"
2) "second"
3) "second_msg"

5. 信息的格式

频道转发的每条信息都是一条带有三个元素的多条批量回复(multi-bulk reply)。 信息的第一个元素标识了信息的类型:

  1. subscribe : 表示当前客户端成功地订阅了信息第二个元素所指示的频道。 而信息的第三个元素则记录了目前客户端已订阅频道的总数。
  2. unsubscribe : 表示当前客户端成功地退订了信息第二个元素所指示的频道。 信息的第三个元素记录了客户端目前仍在订阅的频道数量。 当客户端订阅的频道数量降为 0 时, 客户端不再订阅任何频道, 它可以像往常一样, 执行任何 Redis 命令。
  3. message : 表示这条信息是由某个客户端执行 PUBLISH channel message 命令所发送的, 真正的信息。 信息的第二个元素是信息来源的频道, 而第三个元素则是信息的内容。

四、订阅模式

Redis 的发布与订阅实现支持模式匹配(pattern matching): 客户端可以订阅一个带 * 号的模式, 如果某个/某些频道的名字和这个模式匹配, 那么当有信息发送给这个/这些频道的时候, 客户端也会收到这个/这些频道的信息。 比如说,执行命令

redis> PSUBSCRIBE news.*

的客户端将收到来自 news.art.figurative 、 news.music.jazz 等频道的信息。 客户端订阅的模式里面可以包含多个 glob 风格的通配符, 比如 * 、 ? 和 [...] , 等等。 执行命令

redis> PUNSUBSCRIBE news.*

将退订 news.* 模式, 其他已订阅的模式不会被影响。 通过订阅模式接收到的信息, 和通过订阅频道接收到的信息, 这两者的格式不太一样: 通过订阅模式而接收到的信息的类型为 pmessage : 这代表有某个客户端通过 PUBLISH channel message 向某个频道发送了信息, 而这个频道刚好匹配了当前客户端所订阅的某个模式。 信息的第二个元素记录了被匹配的模式, 第三个元素记录了被匹配的频道的名字, 最后一个元素则记录了信息的实际内容。 客户端处理 PSUBSCRIBE pattern [pattern …] 和 PUNSUBSCRIBE [pattern [pattern …]] 返回值的方式, 和客户端处理 SUBSCRIBE channel [channel …] 和 UNSUBSCRIBE [channel [channel …]] 的方式类似: 通过对信息的第一个元素进行分析, 客户端可以判断接收到的信息是一个真正的信息, 还是 PSUBSCRIBE pattern [pattern …] 或 PUNSUBSCRIBE [pattern [pattern …]] 命令的返回值。

通过频道和模式接收同一条信息

如果客户端订阅的多个模式匹配了同一个频道, 或者客户端同时订阅了某个频道、以及匹配这个频道的某个模式, 那么它可能会多次接收到同一条信息。 举个例子, 如果客户端执行了以下命令:

SUBSCRIBE foo
PSUBSCRIBE f*

那么当有信息发送到频道 foo 时, 客户端将收到两条信息: 一条来自频道 foo ,信息类型为 message ; 另一条来自模式 f* ,信息类型为 pmessage 。

附录

Redis 发布订阅命令

下表列出了 redis 发布订阅常用命令:

序号

命令及描述

1

​PSUBSCRIBE pattern [pattern ...\\]​​ 订阅一个或多个符合给定模式的频道。

2

​PUBSUB subcommand [argument [argument ...\\]]​​ 查看订阅与发布系统状态。

3

​PUBLISH channel message​​ 将信息发送到指定的频道。

4

​PUNSUBSCRIBE [pattern [pattern ...\\]]​​ 退订所有给定模式的频道。

5

​SUBSCRIBE channel [channel ...\\]​​ 订阅给定的一个或多个频道的信息。

6

​UNSUBSCRIBE [channel [channel ...\\]]​​ 指退订给定的频道。


以上是关于#yyds干货盘点# redis | 十七redis之订阅发布的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点# redis | 十四springboot整合redis

#yyds干货盘点# Redis概念和基础

#yyds干货盘点#Redis之主从复制详述

#yyds干货盘点# python-redis-lock锁

redis两种持久化类型 #yyds干货盘点#

#yyds干货盘点# Redis扩展数据类型详解