Redis(三十六):发布与订阅

  • 退订模式

  • 发送消息

    • 将消息发送给频道订阅者
  • 将消息发送给模式订阅者

  • 查看订阅信息

    • Pubsub Channels
  • Pubsub NumSub

  • Pubsub NumPat

  • 总结

Redis的发布与订阅功能由Publish、Subscribe、Psubscribe等命令组成

在这里插入图片描述

频道的订阅与退订


订阅使用的命令是Subscribe或者Psubscribe

Subscribe是指定订阅频道的名字,而Psubscribe是指定订阅频道的模式(名字的模式)

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

Redis将所有频道的订阅关系都保存在服务器状态里面的pubsub_channels字典里面(使用的是字典结构),字典的键是某个被订阅的频道,而键的值则是一个链表,链表里面保存的是所有订阅了该频道的客户端

struct redisServer(

//…

//保存所有客户端与频道的订阅关系

dict *pubsub_channel;

//…

);

在这里插入图片描述

订阅频道

每当客户端执行Subscribe命令去订阅某个或某些频道的时候,服务器都会将客户端与被关联的频道在pubsub_channels字典中进行关联。

并且根据该频道是否有其他订阅者,再细分情况去执行

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

  • 如果链表还未有任何的订阅者,也就是该频道无人订阅,那么它必然不存在于pubsub_channels字典,程序首先会在pubsub_channels字典中为频道创建一个键,然后键对应的值就设置为一个空链表,然后再将此时订阅的客户端添加到链表,称为链表的第一个元素

退订频道

Unsubscribe命令的行为和Subscribe命令的行为正好相反,当一个客户端退订某个频道时候,服务器会将从pubsub_channels中解除客户端与被退订频道之间的关联,也是分情况去进行

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

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

用伪代码去表示

def unsubscribe(*all_input_channels) //参数为退订的频道

#首先遍历要退订的所有频道

for channel in all_input_channels:

#在该频道的订阅者链表中删除退订的客户端

server.pubsub_channels[channel].remove(client);

#判断该频道是否还有订阅者

#订阅者的链表为空,代表没有任何订阅者了,那么将频道从字典中删除

if(len(server.pubsub_channels[channels]) == 0);

server.pubsub_channels.remove(channel)

end for

end unsubscribe

模式的订阅与退订


订阅与退订除了可以指定频道名字去进行,其实还可以指定频道模式去进行(模式是指频道名字模式)

不过按指定频道模式去保存就不在是前面提到的pubsub_channels字典(pubsub_channels),而是会使用服务器状态的另一个属性,名为(pubsub_patterns)的链表

struct redisServer(

//…

//保存所有模式订阅关系

list *pubsub_patterns;

//…

);

pubsub_patterns属性是一个链表,而链表中的每个节点都包含着一个pubsub pattern,这个结构的pattern属性记录了频道被订阅的模式,而client属性则记录了订阅模式的客户端

typedef struct pubsubPattern(

//订阅模式的客户端

redisClient *client;

//被订阅的模式

robj *pattern;

);

在这里插入图片描述

订阅模式

每当客户端执行Psubscribe命令订阅某个或某些类型的时候,服务器会对每个被订阅的模式执行以下操作

  • 新建一个pubsubPattern结构,将结构的pattern属性设置为被订阅的模式,client属性设置为订阅模式的客户端状态

  • 将pubsubPattern结构添加到pubsub_patterns链表的表尾(使用尾插法)

所以可以用下面伪代码来表示

def psubscribe(*all_input_patterns)

#遍历输入的所有模式

for pattern in all_input_patterns:

#创建新的pubsubPattern结构

pubsubPattern = create_new_pubsubPattern();

#记录被订阅的模式,以及订阅模式的客户端

pubsubPattern.client = client;

pubsubPattern.pattern = pattern;

#将新的pubsubPattern追加到pubsub_patterns链表末尾

server.pubsub_patterns.append(pubsubPattern);

end For

end Psubscribe;

退订模式

模式的退订命令Punsubscribe是Psubscribe命令的反操作

当一个客户端Punsubscribe退订某个或某些模式的时候,程序是先要在pubsub_patterns链表中查找并删除那些pattern属性为被退订模式,并且client属性为执行退订命令的客户端的pubsubPattern结构

def punsubscribe(*all_input_patterns)

#遍历所有要退订的模式

for pattern in all_input_patterns:

#遍历pubsub_patterns链表中的所有pubsubPattern结构

for patterns in server.pubsub_patterns:

#如果当前客户端和patterns记录的客户端相同

#并且当前要退订的模式与patterns记录的模式相同

if(client == patterns.client and

pattern == patterns.pattern)

#那么就进行移除

server.pubsub_patterns.remove(patterns)

End for

End for

end punsubscribe;

发送消息


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

分享一套我整理的面试干货,这份文档结合了我多年的面试官经验,站在面试官的角度来告诉你,面试官提的那些问题他最想听到你给他的回答是什么,分享出来帮助那些对前途感到迷茫的朋友。

面试经验技巧篇
  • 经验技巧1 如何巧妙地回答面试官的问题
  • 经验技巧2 如何回答技术性的问题
  • 经验技巧3 如何回答非技术性问题
  • 经验技巧4 如何回答快速估算类问题
  • 经验技巧5 如何回答算法设计问题
  • 经验技巧6 如何回答系统设计题
  • 经验技巧7 如何解决求职中的时间冲突问题
  • 经验技巧8 如果面试问题曾经遇见过,是否要告知面试官
  • 经验技巧9 在被企业拒绝后是否可以再申请
  • 经验技巧10 如何应对自己不会回答的问题
  • 经验技巧11 如何应对面试官的“激将法”语言
  • 经验技巧12 如何处理与面试官持不同观点这个问题
  • 经验技巧13 什么是职场暗语

面试真题篇
  • 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
  • 真题详解2 某知名社交平台软件工程师笔试题
  • 真题详解3 某知名安全软件服务提供商软件工程师笔试题
  • 真题详解4 某知名互联网金融企业软件工程师笔试题
  • 真题详解5 某知名搜索引擎提供商软件工程师笔试题
  • 真题详解6 某初创公司软件工程师笔试题
  • 真题详解7 某知名游戏软件开发公司软件工程师笔试题
  • 真题详解8 某知名电子商务公司软件工程师笔试题
  • 真题详解9 某顶级生活消费类网站软件工程师笔试题
  • 真题详解10 某知名门户网站软件工程师笔试题
  • 真题详解11 某知名互联网金融企业软件工程师笔试题
  • 真题详解12 国内某知名网络设备提供商软件工程师笔试题
  • 真题详解13 国内某顶级手机制造商软件工程师笔试题
  • 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
  • 真题详解15 某著名社交类上市公司软件工程师笔试题
  • 真题详解16 某知名互联网公司软件工程师笔试题
  • 真题详解17 某知名网络安全公司校园招聘技术类笔试题
  • 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题

资料整理不易,点个关注再走吧
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
商软件工程师笔试题

  • 真题详解13 国内某顶级手机制造商软件工程师笔试题
  • 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
  • 真题详解15 某著名社交类上市公司软件工程师笔试题
  • 真题详解16 某知名互联网公司软件工程师笔试题
  • 真题详解17 某知名网络安全公司校园招聘技术类笔试题
  • 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题

[外链图片转存中…(img-fl4zkM6n-1713280984040)]

资料整理不易,点个关注再走吧
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值