redis发布订阅模型

这篇具有很好参考价值的文章主要介绍了redis发布订阅模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

发布与订阅

Redis的发布订阅基于publish,subscribe,psubscribe

订阅

subscribe "news.it"

发布

publish "news.it" "hello"

订阅

redis发布订阅模型,redis,bootstrap,javascript

发布

redis发布订阅模型,redis,bootstrap,javascript

订阅的状态的推进

redis发布订阅模型,redis,bootstrap,javascript

new.it发送消息

redis发布订阅模型,redis,bootstrap,javascript

1.频道订阅和退订

Redis订阅关系保存在服务器状态的pubsub_channels字典

keychannel, value为链表,链表上有订阅该频道的Client

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

如图所示

redis发布订阅模型,redis,bootstrap,javascript

1.1订阅频道subscribe

Client订阅pubsub_channels有两种情况

  • 频道有其他订阅者,把value添加到链表尾部
  • 没有订阅者,就把先创建key再添加value
subscribe "news.sport" "news.movie"

redis发布订阅模型,redis,bootstrap,javascript

伪代码
def subscribe (*all input channels):
	# 遍历输入的所有频道
	for channel in all input channels:
		# 如果channel 不存在于pubsub channels 字典(没有任何订间者)
		# 那么在宇典中添加channel 键,井设置它的值为空链表
		if channel not in server.pubsub channels:
			server.pubsub channels [channel) = (1
		# 将订阅者添加到频道所对应的链表的未尾
		server.pubsub channels [channel].append (client)
1.2 退订频道
unsubscribe "news.sport"  "news.movie"

redis发布订阅模型,redis,bootstrap,javascript

伪代码
def unsubscribe (*all input channels):
		#遍历要退订的所有频道
		for channel in all input channels :
			# 在订阅者链表中副除退订的客户端
			server . pubsub channels [channel1. remove (client)
			# 如果频道已经没有任何订阅者了(订间者链表为空)
			# 那么将频道从字典中刷除
			if len (server.pubsub channels [channel]) == 0 :
				server.pubsub channels. remove (channel)

2.模式订阅和退订

struct redisServer{
  // ...
  //保持所有模式订阅关系
  list *pubsub_patterns;
  // ...
}

pubsub_patterns是链表,每个节点都包括一个pubsub_Patterns结构

typedef struct pubsubPattern{
  //订阅模式Client
  redisClient *client;
  //被订阅的模式
  robj *pattern;
}

示意图

redis发布订阅模型,redis,bootstrap,javascript

client-7,8,9分别在订阅 music.*,book.*,news.*

redis发布订阅模型,redis,bootstrap,javascript

2.1订阅模式psubscribe

客户端执行psubscribe,服务端会执行两个操作

  1. 新建pubsubPattern,讲结构的pattern设置为被订阅的模式
  2. pubsubPattern添加到pubsub_patterns链表尾部

redis发布订阅模型,redis,bootstrap,javascript

执行psubscribe之前的pubsub_patterns

redis发布订阅模型,redis,bootstrap,javascript

执行psubscribe之后的pubsub_patterns

def subscribe (*all_ input patterns):
 #遍历输入的所有模式
	for pattern in all input patterns:
		#创建新的 pubsubPattern 结构
   # 记录被订间的模式,以及订阅模式的容户端
   pubsubPattern = create new pubsubPattern (
   pubsubPattern.client= client
   pubsubPattern.pattern= pattern
   # 将新的 pubsubPattern 追加到pubsubpatterns链表末尾
   server.pubsub patterns.append (pubsubPattern)
2.2 退订模式

punsubscribe

redis发布订阅模型,redis,bootstrap,javascript

当执行退订模式的时候,相应的pubsubPattern结构会被删除

执行punsubscribe "news.*"之前的pubsub_patterns

redis发布订阅模型,redis,bootstrap,javascript

执行punsubscribe "news.*"之后的pubsub_patterns

redis发布订阅模型,redis,bootstrap,javascript

def unsubscribe (*all input patterns) :
		# 遍历所有要退订的模式
		for pattern in all input patterns:
				# 遍历 pubsub patterns 链表中的所有pubsubPattern 结构
				for pubsubPattern in server.pubsub patterns:
							#如果当前客户端和pubsuibPattern 记录的客户端相同
							#并且要退订的模式也和 pubsubPattern 记录的模式相同
							if client == pubsubPattern.client and \
								pattern == pubsubPattern.pattern:
                # 那么将这个pubsubPattern 从链表中利除
                server.pubsub patterns.remove (pubsubPattern)

3.发送消息

PUBLISH <channel> <message>

message发送到channel的订阅者

一个或多个pattern与频道channel匹配

3.1 消息发送频道订阅者

redis发布订阅模型,redis,bootstrap,javascript

PUBLISH "news.it" "hello"		// client-1,client-2,client-3都会收到
伪代码
def channel_publish (channel, message) :
# 如果 channel键不存在于pubsub channels 字典中
# 那么说明 channe1 频道没有任何订阋者
# 程序不做发送动作,直接返回
if channel not in server.pubsub channels:
	return
    
# 运行到这里,说明 channel 频道至少有一个订阅者
# 程序遍历 channe1 频道的订阅者链表
# 将消,息发送给所有订阅者
for subscriber in server.pubsub channels [channel] :
	send message (subscriber, message)
3.2消息发送模式订阅者

redis发布订阅模型,redis,bootstrap,javascript

PUBLISH "news.it" "hello"		// 和news.*匹配,news.*会收到
伪代码
def pattern_publish (channel, message):
	# 遍历所有模式订阅消息
	for pubsubPattern in server.pubsub patterns:
		# 如果频道和模式相匹配
		if match (channel, pubsubPattern.pattern):
			#那么格消息发洪给订回该模式的容户瑞
			send message (pubsubPattern.client, message)

总结的Publish

def publish (channel, message):
		# 将消息发送给 channe1 频道的所有订间者
		channel publish (channel, message)
				#将消息发送给所有和 channel 頻道相匹配的模式的订回者
				pattern publish (channel, message)

4.查看订阅消息

PUBSUB查看频道或者模式相关消息

4.1 pubsub channels
pubsub channels <pattern>(可选)  //pattern可选,选择表示返回匹配的频道
def pubsub channels (pattern=None) :
	#一个列表,用于记录所有符合条件的频道
	channel_list = []
    
	# 遍历服务器中的所有频道
	#(也即是pubsub channels 字典的所有键)
	for channel in server.pubsub channels:
		# 当以下两个条件的任意一个满足时,将频道添加到链表里面:
		#1 )用户没有指定pattezn 参数
		#2 )用户指定了pattern 参数,并且channel 和pattern 匹配
		if (pattern is None) or match (channel, pattern):
		channel list.append (channel)
# 向客户端返回频道列表
return channel_list      

redis发布订阅模型,redis,bootstrap,javascript

被订阅的4个频道

redis> PUBSUB CHANNELS
1)"news. it"
2)"news.sport"
3)"news. business"
4)"news.movie"

进行频道pattern筛选

redis> PUBSUB CHANNELS "news. [is]*"	
  //返回所有名称以"news."开头,并且后面紧跟着一个或多个字母"i"或"s"的频道的列表
1)"news.it"
2)"news. sport"
4.2 pubsub numsub
pubsub numsub [channel-1 channel-2 ...channel-n]  //接受多个频道作为入参,返回这些频道的订阅者
伪代码
def pubsub numsub (*all input channels) :
	# 遍历输入的所有频道
	for channel in all input channels:
		#如果 pubsub channels 宇典中没有 channe1 这个键
		#那么说明 channel 频道没有任何订回者
		if channel not in server.pubsub channels:
			#返回频道名
      reply channel name (channel)
      # 订阅者数量为。
      reply subscribe count (0)
#如果 pubsub channels 字典中存在 channe1 键
# 那么说明channel 频道至少有一个订阅者
else:
      #返回频道名
      reply channel name (channel)
      # 订阅者链表的长度就是订用者数量
      reply subscribe count (len (server .pubsub_channels [channel]))

redis发布订阅模型,redis,bootstrap,javascript

redis> PUBSUB NUMSUB news.it news.sport news.business news.movie
1)"news. it"
2)"3"
3)"news. sport"
4)"2"
5)"news.business"
6)"2"
7)"news. movie"
8)"1"
4.3 pubsub numpat

返回服务器当前被订阅模式的数量

伪代码
def pubsub_numpat():
		# pubsub_patterns 链表长度是被订阅数量
reply pattern count (len(server.pubsub patterns))

redis发布订阅模型,redis,bootstrap,javascript

对于上方链表来说,执行pubsub numpat结果文章来源地址https://www.toymoban.com/news/detail-635750.html

redis> pubsub numpat
(integer) 3

5.回顾

  1. 服务器在pubsub_channels保存频道订阅关系,subscribeunsubscribe
  2. 服务器在pubsub_patterns保存模式订阅关系,psubscribepunsubscribe
  3. publish发送消息
  4. pubsub读取pubsub_channelspubsub_patterns来实现

到了这里,关于redis发布订阅模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA 实现 Redis 发布订阅

    发布订阅: 消息发布者发布消息 和 消息订阅者接收消息 ,两者之间通过某种媒介联系起来 例如订杂志,当自己订阅了爱格杂志,每个月会发刊一本。到发布的时候派送员将杂志送到自己手上就能看到杂志内容。只有我们订阅了该杂志才会派送给我们 Redis 发布订阅(pub/su

    2024年02月14日
    浏览(39)
  • Redis 消息队列和发布订阅

    采用redis 三种方案: ● 生产者消费者:一个消息只能有一个消费者 ● 发布者订阅者:一个消息可以被多个消费者收到 ● stream模式:实现队列和广播模式 Producer调用redis的lpush往特定key里放消息,Consumer调用brpop去不断监听key。 1、利用redis的链表,存储数据,实现队列模式

    2024年01月18日
    浏览(44)
  • redis发布订阅模式的应用

    小体量系统,某些特定场景需要做异步处理。如操作日志记录、发送消息、数据excel导入等。并发量不大,主要作用是异步批处理数据,提高响应速度,改善用户体验,不至于页面卡半天。用消息队列的话显得很笨重,牛刀杀鸡,不利于项目的快速布署和影响项目稳定。在这

    2024年02月11日
    浏览(46)
  • JavaScript 简单实现观察者模式和发布-订阅模式

    大家好,我是南木元元,热衷分享有趣实用的文章。今天来聊聊设计模式中常用的观察者模式和发布-订阅模式。 观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。 如何理解这句话呢?来举个生活中的例子

    2024年02月12日
    浏览(106)
  • Redis消息传递:发布订阅模式详解

    目录 1.Redis发布订阅简介 2.发布/订阅使用    2.1 基于频道(Channel)的发布/订阅    2.2 基于模式(pattern)的发布/订阅 3.深入理解Redis的订阅发布机制    3.1 基于频道(Channel)的发布/订阅如何实现的?    3.2 基于模式(Pattern)的发布/订阅如何实现的?    3.3 SpringBoot结合Redis发布

    2024年02月12日
    浏览(45)
  • Redis实现消息的发布和订阅

    4.1 发送消息 4.2 接收消息

    2024年02月13日
    浏览(42)
  • 【Redis】Pub/Sub(发布/订阅)

    Pub/Sub(发布/订阅)是一种消息传递模式,其中消息发送者(发布者)将消息发布到一个或多个主题(topics)或频道(channels),而消息接收者(订阅者)订阅特定的主题或频道以接收消息。 在Pub/Sub模式中,发布者和订阅者不直接通信,而是通过一个中介(通常称为消息代理

    2024年02月16日
    浏览(36)
  • JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式

    个人简介 👀 个人主页: 前端杂货铺 🙋‍♂️ 学习方向: 主攻前端方向,正逐渐往全干发展 📃 个人状态: 研发工程师,现效力于中国工业软件事业 🚀 人生格言: 积跬步至千里,积小流成江海 🥇 推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒

    2024年02月09日
    浏览(49)
  • Redis发布订阅机制学习|kafka相关经验

    Redis 键值数据库 key value NoSql 第一章: 差异 #1 structured 结构化 约束 primary unique unsigned #2 relational 关联的 #3 SQL查询 例 select id, name, age from tb_user where id=1 redis get user:1 mongoDB db.users.find({_id: 1}) elasticsearch GET http://localhost:9200/users/1 #4 事务 ACID 基本一致 无事务 键值类型 Redis 文档类

    2024年02月15日
    浏览(40)
  • Redis(发布订阅、事务、redis整合springboot、集成 Spring Cache)

    目录 一.redis的发布订阅 1、什么 是发布和订阅 2、Redis的发布和订阅 3、发布订阅的代码实现 二.Redis事务 1.事务简介 1、在事务执行之前 如果监听的key的值有变化就不能执行 2、在事务执行之前 如果监听的key的值没有变化就能执行 3、Exec之前就出现错误 4、Exec之后出现的错误

    2024年01月24日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包