图解redis发布和订阅

news2024/11/10 14:42:05

目录

1.什么是发布订阅

1.1概念

1.2发布订阅过程

1.3发布订阅分为两类

2. 频道的订阅与退订

2.1subcribe

2.2退订频道

3. 模式的订阅和退订

3.1模式的订阅

3.2punsubscribe

4.频道和模式的发布

4.1频道的发布

4.2模式的发布


1.什么是发布订阅

1.1概念

1.发布订阅模式又叫观察者模式,是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
2.主要的目的是解耦消息发布者和消息订阅者之间的耦合,这点和设计模式中的观察者模式比较相似。
3.由三部分组成:发布者(pub),订阅者(sub)和频道(channel)
4.Redis 客户端可以订阅任意数量的频道。
5.Redis 在订阅者和发布者之间起到了消息路由的功能。

1.2发布订阅过程

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

在这里插入图片描述

1.3发布订阅分为两类

 1.频道的发布订阅

 2.模式的发布订阅

2. 频道的订阅与退订

2.1subcribe

当一个客户端执行SUBSCRIBE命令订阅某个或某些频道的时候, 这个客户端与被订阅频道之间就建立起了一种订阅关系

格式  SUBSCRIBE channel [channel …]

底层原理 :

1.pubsub_channels字典 

Redis将所有频道的订阅关系都保存在服务器状态

struct redisServer {
// ...
//
保存所有频道的订阅关系
dict *pubsub_channels;
// ...
};

图形示意:

client-1、client-2、client-3三个客户端正在订阅"news.it"频道。

·客户端client-4正在订阅"news.sport"频道。

·client-5和client-6两个客户端正在订阅"news.business"频道。

 2.情况分类

1.如果频道已经有其他订阅者,那么它在pubsub_channels字典中必 然有相应的订阅者链表,程序唯一要做的就是将客户端添加到订阅者链 表的末尾。

2·如果频道还未有任何订阅者,那么它必然不存在于 pubsub_channels字典,程序首先要在pubsub_channels字典中为频道创建 一个键,并将这个键的值设置为空链表,然后再将客户端添加到链表, 成为链表的第一个元素

图形示意

SUBSCRIBE "news.sport" "news.movie”

1. ·更新后的pubsub_channels字典新增了"news.movie"键,该键对应的 链表值只包含一个client-10086节点,表示目前只有client-10086一个客户 端在订阅"news.movie"频道

2.至于原本就已经有客户端在订阅的"news.sport"频道,client-10086 的节点放在了频道对应链表的末尾

2.2退订频道

格式 unsub channel message

底层原理:

UNSUBSCRIBE命令的行为和SUBSCRIBE命令的行为正好相反, 当一个客户端退订某个或某些频道的时候,服务器将从pubsub_channels 中解除客户端与被退订频道之间的关联

图形示意:

·程序会根据被退订频道的名字,在pubsub_channels字典中找到频 道对应的订阅者链表,然后从订阅者链表中删除退订客户端的信息。

·如果删除退订客户端之后,频道的订阅者链表变成了空链表,那 么说明这个频道已经没有任何订阅者了,程序将从pubsub_channels字典 中删除频道对应的键

执行之后 

UNSUBSCRIBE "news.sport" "news.movie"

 

3. 模式的订阅和退订

3.1模式的订阅

1.psubscribe命令

  • 格式: PSUBSCRIBE pattern [pattern …]

  • eg : PSUBSCRIBE China* 订阅以China为开头的所有频道

  • 底层原理

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

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

    3.client 属性保存着订阅模式的客户端,而 pattern 属性则保存着被订阅的模式。

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

    举个例子,下图展示了一个包含两个模式的 pubsub_patterns 链表, 其中 client123 和 client256 都正在订阅 tweet.shop.* 模式
    在这里插入图片描述

  • 如果这时客户端 client10086 执行 PSUBSCRIBE broadcast.list.* , 么 pubsub_patterns 链表将被更新成这样:

  •  在这里插入图片描述

 note1

假设客户端同时订阅了某种模式和符合该模式的某个频道,那么发送给这个频道的消息将被客户端接收到两次,只不过这两条消息的类型不同,一个是message类型,一个是pmessage类型,但其内容相同

3.2punsubscribe

格式: PUNSUBSCRIBE [pattern [pattern …]]

原理:这个命令执行的是订阅模式的反操作:程序会删除redisServer.pubsub_patterns 链表中,所有和被退订模式相关联的 pubsubPattern 结构,这样客户端就不会再收到和模式相匹配的频道发来的信息。

note1 1.在SUBSCRIBE,PSUBSCRIBE,UNSUBSCRIBE和PUNSUBSCRIBE命令中,其返回值都包含了该客户端当前订阅的频道和模式的数量,当这个数量变为0时,该客户端会自动退出订阅状态。

2.PUBLISH和SUBSCRIBE的缺陷在于客户端必须一直在线才能接收到消息,断线可能会导致客户端丢失消息,除此之外,旧版的redis可能会由于订阅者消费不够快而变的不稳定导致崩溃,甚至被管理员杀掉

4.频道和模式的发布

4.1频道的发布

命令 PUSHLISH<channel><message>

因为服务器状态中的pubsub_channels字典记录了所有频道的订阅关 系,所以为了将消息发送给channel频道的所有订阅者,PUBLISH命令 要做的就是在pubsub_channels字典里找到频道channel的订阅者名单(一 个链表),然后将消息发送给名单上的所有客户端

例子1

PUBLISH "news.it" "hello"

那么PUBLISH命令将在pubsub_channels字典中查找键"news.it"对应 的链表值,并通过遍历链表将消息"hello"发送给"news.it"频道的三个订 阅者:client-1、client-2和client-3。

4.2模式的发布

发送信息到模式的工作也是由 PUBLISH 命令进行的。PUBLISH 除了将 message 发送到所有订阅 channel 的客户端之外,它还会将 channel 和 pubsub_patterns 中的模式进行对比,如果 channel 和某个模式匹配的话,那么也将 message 发送到订阅那个模式的客户端
 

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

当有信息发送到 tweet.shop.kindle 频道时, 信息除了发送给 clientX 和 clientY 之外, 还会发送给订阅 tweet.shop.* 模式的 client123 和 client256 

在这里插入图片描述

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417257.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【电源专题】案例:充电芯片如何配置NTC偏置网络设定充电温度区间

背景 充电芯片是需要检测电池内部的NTC电阻来得到电池此时的温度,然后根据温度来判断自己是否要进行充电。因此在导入充电芯片过程中,我们需要设置NTC的偏置网络来设定能充电的温度范围。如下图所示为SGM41523芯片的典型应用图: RT1和RT2为NTC的偏置网络。 在规格书的更详细…

【U8+】修改用友U8+填制凭证界面字体大小

【问题描述】 在使用用友U8软件填制凭证功能时&#xff0c; 觉得【填制凭证】界面字体太小&#xff0c;看着不方便。 想要进行调整。 【解决方法】 1、打开填制凭证界面&#xff0c; 点击最上方【选项】按钮&#xff1b; 2、在弹出的凭证选项设置窗口中&#xff0c; 找到【凭…

PHP语言请求示例,电商商品详情接口(item_get-根据ID取商品详情)代码封装教程

item_get-根据ID取商品详情接口 通过代码封装该接口可以拿到商品标题&#xff0c;商品价格&#xff0c;商品促销信息&#xff0c;商品优惠价&#xff0c;商品库存&#xff0c;sku属性&#xff0c;商品图片&#xff0c;desc图片&#xff0c;desc描述&#xff0c;sku图片&#xf…

抓包工具Wireshark安装与使用

windows下安装 下载安装包 Npcap wireshark依赖于Npcap或者Winpcap软件捕获网络实时数据。这里选择Npcap。下载地址&#xff1a;https://npcap.com/#download。Wireshark Wireshark是一个开源的网络数据包分析器。该分析器尽可能详细地展示捕获的包数据。下载地址&#xff1a…

C++ 数组、指针、数组指针、指针数组、多级指针、STL-map、结构体 的 初始化 及其 初始化赋值

C 数组、指针、数组指针、指针数组、多级指针、STL-map、结构体 的 初始化 及其 初始化赋值C 数组、指针、数组指针、指针数组、多级指针、STL-map、结构体 的 初始化 及其 初始化赋值C 数组、指针、数组指针、指针数组、多级指针数组一维数组初始化&#xff1a;二维数组初始化…

8.1 假设验证的基本概念

学习目标&#xff1a; 要学习假设检验的基本概念&#xff0c;我会按照以下步骤进行&#xff1a; 了解假设检验的基本概念&#xff1a;假设检验是一种统计推断方法&#xff0c;用于判断某个假设是否成立。一般来说&#xff0c;假设检验包括原假设和备择假设两个假设&#xff0c…

语雀笔记备份导出

参考: https://www.cnblogs.com/ssslinppp/p/17020303.htmlhttps://github.com/yuque/yuque-exporterhttps://zhuanlan.zhihu.com/p/582287220https://www.yuque.com/duzh929/blog/ocffqghttps://www.yuque.com/hijiaobu/datalife/onf6sy#BKajf 现在需要超级管理员,若是没有超级…

JDK8新特性 (Lambda表达式和Stream流式编程)

目录 一&#xff1a;JDK8新特性 1. Java SE的发展历史 2. 了解Open JDK 和 Oracle JDK 3. JDK 8新特性 3.1 Lambda表达式&#xff08;重点&#xff09; 3.2 接口的增强 3.3 函数式接口 3.4 方法引用 3.5 集合之Stream流式操作&#xff08;重点&#xff09; 3.6 新的时…

Windows wsl连接网络代理

使用 WSL 访问网络应用程序 | Microsoft Learn 为 WSL2 一键设置代理 - 知乎 (zhihu.com) 介绍 本文介绍开通了Windows WSL子系统之后&#xff0c;怎么在两者之间进行网络通讯&#xff1b;对在windows系统中开启了代理以后&#xff0c;如何在WSL中设置网络代理问题进行了详细…

光萤CEO陈海洲:平台模式将成为户用分布式光伏市场的主流 | 爱分析调研

近两年来&#xff0c;随着国家“双碳”目标的确立&#xff0c;清洁能源迎来重要发展机遇&#xff0c;其中户用分布式光伏因其对土地资源占用少、离用电侧距离近以及与国家乡村振兴战略共振的效果而受到显著的政策倾斜性支持。2020-2022年户用分布式光伏新增装机量持续攀升&…

【C++基础】auto关键字(C++11)(auto的使用细则;auto不能推导的场景;auto的使用场景;基于范围的for循环)

九、auto关键字 9.1 auto简介 在早期C/C(C98)中auto的含义是&#xff1a;使用auto修饰的变量&#xff0c;是具有自动存储器的局部变量&#xff0c;但遗憾的是一直没有人去使用它。因为在函数内定义的变量默认就是局部变量。 C11中&#xff0c;标准委员会赋予了auto全新的含义…

目标检测基础之IOU计算

目标检测基础之IOU计算概念理解——什么是IOUdemo后记概念理解——什么是IOU IOU 交并比&#xff08;Intersection over Union&#xff09;&#xff0c;从字面上很容易理解&#xff1a;计算交集在并集的比重。从网上截张图看看 IOUA∩BA∪BIOU \frac{A \cap B}{A \cup B} IO…

【Java版oj】day32淘宝网店、斐波那契凤尾

目录 一、淘宝网店 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、斐波那契凤尾 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 一、淘宝网店…

idea将本地项目上传git

idea将本地项目上传git 第一步&#xff1a;菜单栏 VCS——>import into Version control——>Create git Repository——>弹出框找到选中自己项目——>点击OK 第二步&#xff1a;选中项目右键 ——>git——>Add 文件会变成绿色表示成功 第三步:VCS——>co…

Nginx的概述与配置

一、Nginx概述 1、Nginx的特点 一款高性能、轻量级web服务 • 稳定性高 • 系统资源消耗低高 • 对HTTP并发连接的处理能力 单台物理服务器可支持30000~50000个并发请求 2、 Nginx编译安装 • 安装支持软件 • 创建运行用户、组 • 编译安装Nginx 3、Nginx运行控制 …

Java面试突击班(抓住金九银十) 持续更新中

文章目录1.Java中线程的实现方式&#xff1f;2. Java线程中的状态&#xff1f;3. Java中如何停止线程&#xff1f;4. Java中Sleep和wait方法的区别&#xff1f;5.扩展—— P5典型 P6典型 P7典型6.并发编程的三大特性原子性什么时并发编程得原子性保证并发编程得原子性可见性什么…

【CSS】固定定位示例 ( 屏幕左右两侧广告栏 | 开发要点分析 | 代码示例 )

文章目录一、开发要点分析二、代码示例一、开发要点分析 实现下图样式 : 中间部分是网页内容 , 左右两侧是 固定广告栏 , 不管浏览器如何滚动 , 缩放 , 该左右两侧广告栏不变 ; 标签结构分析 : 上述页面中 , 中心的版心盒子 与 左侧广告栏 / 右侧广告栏 是兄弟关系 ; <div …

如何在rust中使用泛型,trait对象的总结以及kv sever(3)

可以说在 Rust 开发中&#xff0c;泛型编程是我们必须掌握的一项技能。在你构建每一个数据结构或者函数时&#xff0c;最好都问问自己&#xff1a;**我是否有必要在此刻就把类型定死&#xff1f;**是不是可以把这个决策延迟到尽可能靠后的时刻&#xff0c;这样可以为未来留有余…

谷歌的Bard和OpenAI的GPT4的对比

前言 随着上个月21日谷歌面向公众开放人工智能聊天机器人Bard的访问权限&#xff0c;同样是上个月的14日OpenAI为聊天机器人ChatGPT发布的最新语言模型&#xff1a;GPT-4的问世&#xff0c;可以说关于ChatGPT应用的推出进入了百家争鸣的情况&#xff0c;而且竞争变得激烈起来&a…

手把手教你Temporal Fusion Transformer——Pytorch实战

建立了一个关于能源需求预测的端到端项目&#xff1a; 如何为 TFT 格式准备我们的数据。 如何构建、训练和评估 TFT 模型。 如何获取对验证数据和样本外预测的预测。 如何使用built-in model的可解释注意力机制计算特征重要性、季节性模式和极端事件鲁棒性。 什么是Temporal F…