Redis发布订阅和Stream

Redis发布订阅和Stream,第1张

发布订单系统是日常开发中经常会用到的功能。简单来说,就是发布者发布消息,订阅者就会接受到消息并进行相应的处理,如下图所示。

Redis为我们提供了发布/订阅的功能模块PubSub,可以用于消息传递。

其中发布者publisher、订阅者subscriber都是redis客户端,channel则是redis服务器。

发布者publisher向channel发送消息,订阅该channel的subscriber就会接收到消息。

发布消息publish

订阅test1、test2的客户端会收到消息

按照上述这种方式,如果 订阅者subscriber想要订阅多个channel 则需要同时指定多个channel的名称,redis为了解决这个问题提供 psubscribe模式匹配 这种订阅方式,可以通过通配符的方式匹配频道。

发布消息

之前订阅ch*的客户端就会收到cha频道和china频道的消息,这样就一次性订阅多个频道

redis服务端存储了订阅频道/模式的客户端列表

相当于如果客户端订阅一个频道 ,那么服务端的 pubsub_channels 就会存储一条数据, pubsub_channels 其实是一个链表,key对应channel,value对应客户端列表,根据key订阅的频道,就可以找到订阅该频道的所有客户端。

同时如果客户端订阅一个模式 pubsub_patterns 也会新增一条数据,记录当前客户端订阅的模式, pubsub_patterns 也有自己的数据结构,其中就包含了客户端以及模式。

当发布者向某个频道发布消息时,就会遍历 pubsub_channels 找到订阅该频道的客户端列表,依次向这些客户端发送消息。

然后遍历 pubsub_patterns 找到符合当前频道的模式,同时找到模式对应的客户端,然后向客户端发送消息。

虽然Redis提供了发布/订阅的功能,但是并不完善,导致基本没有合适的场景能够使用。

PubSub缺点:

直到Redis5.0出现之后,出现了Stream这种数据结构,才终于完善了Redis的消息机制

Stream实际上就是一个消息列表,只是他几乎实现了消息队列所需要的所有功能,包括:

同时需要注意的是Stream只是一个数据结构,他不会主动把消息推送给消费者,需要消费者主动来消费数据

每个Stream都有唯一的名称,它就是Redis的key,首次使用 xadd 指令追加消息时自动创建。

常见操作命令如下表:

如果客户端希望知道自身消费到第几条数据了,那么就需要记录一下当前消费的消息ID,下次再次消费的时候就从上次消费的消息ID开始读取数据即可。

消费组中多了一个游标 last_delivered_id ,表示当前消费到了哪一条数据。同时所有的数据都是待处理消息( PEL ),只有消费者处理完毕之后使用 ack 指令告知redis服务器,数据才会从 PEL 中移除,确认后的消息就无法再次消费。

如果接收到的消息比较多,为了避免Stream过长,可以选择指定Stream的最大长度,一旦到达了最大长度,就会从最早的消息开始清除,保证Stream中最新的消息。

最近项目中,有个功能点是利用redis的发布订阅机制,进行服务器本地缓存数据同步。

由于redis发布订阅功能的可靠性较差,在项目中出现了有服务器没有订阅成功问题,以及服务器订阅消息不及时,导致部分业务受到影响。所以将redis通知本地缓存的机制改为了使用redis做二级缓存。

虽然Redis能够实现发布/订阅的功能,但是有如下缺点,所以选用前需谨慎考虑

和常规的MQ不同,redis实现的发布/订阅模型消息无法持久化,一经发布,即使没有任何订阅方处理,该条消息就会丢失

即发布方不会确保订阅方成功接收

广播机制无法通过添加多个消费方增强消费能力,因为这和发布/订阅模型本身的目的是不符的.广播机制的目的是一个一个发布者被多个订阅进行不同的处理

由于Redis发布/订阅模型存在的缺陷,所以使用前需要考虑如下几点

1.对于消息处理可靠性要求不强

2.消费能力无需通过增加消费方进行增强

————————————————

原文链接: https://blog.csdn.net/weixin_32394085/article/details/105006123


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/677855.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-07-29
下一篇2023-07-29

发表评论

登录后才能评论

评论列表(0条)

    保存