Redis发布订阅与Stream

本文介绍了Redis的发布订阅功能,包括频道订阅、模式订阅、消息发送及查看订阅信息,强调了PubSub的缺点。同时,文章深入讨论了Redis Stream,包括消息ID、消息内容、消费模式和Stream管理,探讨了如何处理过多消息和与Kafka的对比。
摘要由CSDN通过智能技术生成

目录

发布与订阅简介

频道的订阅与退订

订阅频道

退订频道

模式的订阅与退订

订阅模式

退订模式

发送消息

将消息发送给频道订阅者

将消息发送给模式订阅者

查看订阅信息

PUBSUB CHANNELS

PUBSUB NUMSUB

PUBSUB NUMPAT

PubSub 的缺点

Stream

消息 ID 和消息内容

增删改查示例

独立消费示例

创建消费者示例

组内消费示例

Stream 消息太多怎么办?

PEL 是如何避免消息丢失的?

Redis Stream Vs Kafka


发布与订阅简介

Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。

通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,从而成为这些频道的订阅者(subscriber) : 每当有其他客户端向被订阅的频道发送消息(message)时,频道的所有订阅者都会收到这条消息。

在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如RocketMQ等。

举个例子,假设A、B、C三个客户端都执行了命令:

那么这三个客户端就是"news.it"频道的 订阅者,如图所示。

如果这时某个客户端执行命令

向"news.it"频道发送消息"hello", 那么"news.it"的三个订阅者都将收到这 条消息,如图所示。

除了订阅频道之外,客户端还可以通过执行SUBSCRIBE命令订阅一个或多个模式从而成为这些模式的订阅者:每当有其 他客户端向某个频道发送消息时,消息不仅 会被发送给这个频道的所有订阅者,它还会被发送给所有与这个频道相匹配的模式的订阅者。

举个例子,假设如图18-3所示:

客户端A正在订阅频道"news.it"

客户端B正在订阅频道"news.et"

客户端C和客户端D正在订阅与"news.it"频道和"news.et"频道相匹配的模 式"news. [ie]t"

如果这时某个客户端执行命令向"news.it"频道发送消息"hello", 那么不仅正在订阅"news.it"频道的客户端 A会收到消息,客户端C和客户端D也同样会收到消息,因为这两个客户端正在订阅匹配 "news.it"频道的"news. [ie]t"模式,如图所示。

向"news.et"频道发送消息"world", 那么不仅正在订阅"news.et"频道的客户端 B会收到消息,客户端C和客户端D也同样会收到消息,因为这两个客户端正在订阅匹配 "news.et"频道的"news. [ie] t"模式,如图所示。

频道的订阅与退订

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

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

比如说,图就展示了一个pubsub_channels字典示例,这个字典记录了以下信息:

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

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

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

订阅频道

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

根据频道是否已经有其他订阅者,关联操作分为两种情况执行:

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

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

举个例子,假设服务器pubsub_channels字典的当前状态如图所示

那么当客 户端client-10086执行命令

SUBSCRIBE "news.sport" "news.movie"

之后,pubsub_channels字典将更新至图所示的状态,其中用虚线包围的是新添加的节点:

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

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

SUBSCRIBE命令的实现可以用以下伪代码来描述:

退订频道

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

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

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

举个例子,假设pubsub_channels的当前状态如图所示

那么当客户端 client一10086执行命令

UNSUBSCRIBE "news.sport" "news.movie"

之后,图中用虚线包围的两个节点将被删除(如图所示):

在pubsub_channels字典更新之后,client-10086的信息已经从"news. sport"频道和"news .mo"Vie"频道的订阅者链表中被删除了。

另外,因为删除client-10086之后,频道"news. movie"已经没有任何订阅 者,因此键"news.movie"也从字典中被删除了。

UNSUBSCRIBE命令的实现可以用以下伪代码来描述:

模式的订阅与退订

前面说过,服务器将所有频道的订阅关系都保存在服务器状态的pubsub_channels 属性里面,与此类似,服务器也将所有模式的订阅关系都保存在服务器状态的pubsub_ patterns属性里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值