IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Redis进阶-发布订阅简介 -> 正文阅读

[大数据]Redis进阶-发布订阅简介

1. Redis 发布订阅简介

Redis 发布订阅(pub/sub)是一种消息通信模式:

  • 发送者(pub):发送消息
  • 订阅者(sub):接收消息

Redis的 subscribe命令可以让客户端订阅任意数量的频道,每当有新的信息发送到被订阅的频道的时候,信息就会被发送给所有订阅指定频道的客户端。

例如,频道 channel1 被三个客户端订阅:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pB7x65Wq-1646223163632)(2021-12-19-Redis消息传递.assets/db-redis-sub-1.svg)]

当有新的消息被 publish 命令送到此频道上,这个消息就会被发布给这三个订阅了该频道的客户端。

在这里插入图片描述

2. Redis 发布/订阅使用

Redis 有两种发布/订阅模式:

  • 基于频道(channel)的发布/订阅
  • 基于模式(pattern)的发布/订阅

2.1 基于频道(channel)的发布/订阅

“发布/订阅” 模式包含两种角色,发布者、订阅者,就像定杂志的客户和杂志。

发布者可以向指定的频道发送消息,订阅者可以订阅一个或者多个频道,所有订阅此频道的订阅者都能收到发布者发布在这个频道上的消息

类比于我们定杂志和获取杂志内容的全过程,杂志是消息,我们是订阅者,发布者将内容发布在杂志上,我们可以订阅不同的杂志。

在这里插入图片描述

  • 发布者发布消息

发布者发布消息的命令是 publish ,用法是 publish channle message:xx,例如向 channel:1 说一声 hello:

127.0.0.1:6379> publish channel:1 hello
(integer) 1

这样消息就发送出去了,返回值代表了收到这条消息的订阅者的数量。注意,发出去的消息不会被持久化。也就是有客户端订阅了 channel:1 后只能接收到后续发布到该频道的消息,之前的消息就收不到了。

  • 订阅者订阅频道

订阅频道的命令是 subscribe,可以同时订阅多个频道,用法是 subscribe channelname ... ,例如新开一个客户端订阅上面的例子的频道:

127.0.0.1:6379> subscribe channel:1
Reading messages... (press Ctrl-C to quit)
1) "subscribe" // 消息类型
2) "channel:1" // 频道
3) "hello" // 消息内容

执行上面的命令客户端会进入订阅状态,处于此状态的客户端不能使用除了 subscribe、unsubscribe、psubscribe、punsubscribe 四个属于 “发布/订阅” 模式之外的命令,否则会报错。

进入订阅状态之后的客户端可能会收到 3种类型 的回复。每种类型的回复都包含3个值:

  • 第一个值:消息类型,根据这个值,第二第三个值会不同。

消息类型的取值可能是以下3个

  • subscribe:表示订阅成功的反馈信息,第二个值是订阅成功的频道信息,第三个值是当前客户端订阅的频道数量。
  • message:表示收到的消息,第二个值此时是表示生产消息的频道名称,第三个值此时是消息的内容。
  • unsubscribe:表示成功取消订阅某个频道,此时第二个值是对应取消的频道名称,第三个值是当前客户端订阅的频道数量,当此时值为 0 时的客户端会退出订阅状态,之后就可以执行其它非 “发布/订阅” 模式的命令了

2.2 基于模式(partten)的发布/订阅

如果有某个或者某i写模式和这个频道匹配的话,那么所有订阅这个或者这些频道的客户端同样也会收到频道的消息。

下图展示了一个带有频道和模式的例子, 其中 tweet.shop.* 模式匹配了 tweet.shop.kindle 频道和 tweet.shop.ipad 频道, 并且有不同的客户端分别订阅它们三个:
在这里插入图片描述

client123、client256 订阅了 twee.shop.* 这个模式,那么当这个模式下的任何一个频道有消息,都会通知给这俩客户端:

在这里插入图片描述

在这里插入图片描述

2.2.1 基于模式的例子

通配符中 表示 1个占位符,* 表示任意个占位符(包括0),* 表示1个以上的占位符。

  • publish 发布
127.0.0.1:6379> publish c m1
(integer) 0
127.0.0.1:6379> publish c1 m1
(integer) 1
127.0.0.1:6379> publish c11 m1
(integer) 0
127.0.0.1:6379> publish b m1
(integer) 1
127.0.0.1:6379> publish b1 m1
(integer) 1
127.0.0.1:6379> publish b11 m1
(integer) 1
127.0.0.1:6379> publish d m1
(integer) 0
127.0.0.1:6379> publish d1 m1
(integer) 1
127.0.0.1:6379> publish d11 m1
(integer) 1
  • psubscribe 订阅
127.0.0.1:6379> psubscribe c? b* d?*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "c?"
3) (integer) 1
1) "psubscribe"
2) "b*"
3) (integer) 2
1) "psubscribe"
2) "d?*"
3) (integer) 3
1) "pmessage"
2) "c?"
3) "c1"
4) "m1"
1) "pmessage"
2) "b*"
3) "b"
4) "m1"
1) "pmessage"
2) "b*"
3) "b1"
4) "m1"
1) "pmessage"
2) "b*"
3) "b11"
4) "m1"
1) "pmessage"
2) "d?*"
3) "d1"
4) "m1"
1) "pmessage"
2) "d?*"
3) "d11"
4) "m1"
  • 注意点
  1. 使用 psubscribe 命令可以重复订阅同一个频道,如客户端执行了 psubscribe c? c*,那么这里如果向 c1 发布消息,那么客户端可以收到两条消一样的消息,publish 命令返回的值是2(虽然是一个客户端)。同样的,如果有另一个客户端执行了subscribe c1psubscribe c?*的话,向c1发送一条消息该客户端也会手到两条消息(但是是两种类型: messagepmessage),同时 publish命令也返回 2(虽然还是同一个客户端),感觉就是造成一种假象。
  2. punsubscribe 命令可以退订的规则,用法:punsubscribe [partter[partten]],可以套娃,如果没有参数则会退订所有规则
  3. 通过 punsubscribe 才能退订通过 psubscribe命令订阅的规则,不影响直接通过 subscribe 命令订阅的频道,命令都是一一对应;另外需要注意的是 punsubscribe 命令退订某个规则时不会将其中的通配符展开,而是要进行严格的字符串匹配,所以 psubscribe * 无法退订 c* 的模式 ,而是必须使用 punsubscribe c* 才可以退订。

3. 深入理解基于频道(channel)的发布/订阅如何实现?

底层是啥?我们来看一张图:

3.1 数据结构

在这里插入图片描述

我们可以看到底层是通过字典 (图中的 pubsub_channels)实现的,这个字典就是用于保存订阅频道的信息:

  • :正在被订阅的频道
  • :一个链表,保存所有订阅这个频道的客户端

3.2 订阅

当客户端调用了 subscribe 命令时,程序就会将客户端和对应要订阅的频道在 pubsub_channels 字典中关联起来。

例子:比如客户端 client10086 执行命令 subscribe channel1 channel2 channel3,对应字典应该变成如下这样:

在这里插入图片描述

3.3 发布

当调用 publish channel message 命令,程序首先根据 channel 定位到字典的键,然后将信息发送欸字典值链表中的所有客户端。

举个例子:3.1中的图,如果向 channel2 频道发送消息,那么这个频道所对应的链表中的客户端都可以收到消息。

3.4 退订

使用 unsubscribe 命令可以退订指定的频道,这个命令执行的是订阅的反操作:它从 pubsub_channel 字典的给定键中,删除键中链表中对应的客户端的结点信息,这样被退订的频道的信息就不会再发送给这个客户端。

4. 深入理解基于模式(Pattern)的发布/订阅如何实现的?

底层是 pubsubPattern 结点的链表。

4.1 数据结构

redisServer.pubsub_patterns 属性是一个链表,链表中保存着所有和模式相关的信息:

struct redisServer {
    // ...
    list *pubsub_patterns;
    // ...
};

链表中的每个结点都包含一个 redis.h/pubsubPattern 结构:

typedef struct pubsubPattern {
    redisClient *client; // 保存着订阅模式的客户端
    robj *pattern; // 保存着订阅的模式
} pubsubPattern;

每当调用 psubscribe 命令订阅一个模式的时候,程序就创建一个包含客户端信息和被订阅模式的 pubsubPattern 结构,并将该结构添加到 redisServer.pubsub_patterns 链表中。

在这里插入图片描述

4.2 订阅

就继续拿 client10086 来说吧,它执行 psubscribe broadcast.list.* 指令之后,pubsub_patterns 链表将被更新为:

在这里插入图片描述

通过遍历整个 pubsub_pattern 链表,程序就可以检查现在所有正在被订阅的模式,以及订阅这些模式客户端信息。

4.3 发布

发送信息到模式的工作也是由 publish 命令进行的,显然就是匹配模式获得 channels,然后再把消息发送给客户端。

4.4 退订

使用 punsubscribe 命令可以退订指定的模式,必须精确说明模式名称,不能用通配符去匹配。程序会根据这个命令去删除 redisServer.pubsub_pattern 链表中所有与被退订的模式相关联的 pubsubPattern 结构,这样客户端就不会收到被退订的模式所匹配的频道发来的消息

5. SpringBoot 结合 Redis发布/订阅实例

这个的话,CSDN去一找就可以找到相关的内容。

码云仓库同步笔记,可自取欢迎各位star指正:https://gitee.com/noblegasesgoo/notes

如果出错希望评论区大佬互相讨论指正,维护社区健康大家一起出一份力,不能有容忍错误知识。
										—————————————————————— 爱你们的 noblegasesgoo
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-03 16:21:05  更:2022-03-03 16:21:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:31:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码