乐趣区

关于后端:云原生消息队列Pulsar浅析

简介:云原生音讯队列 Pulsar 浅析
一、前言
Pulsar 是一个多租户,高性能的服务间音讯解决方案。最后由 Yahoo 开发,当初由 Apache Software Foundation 负责。Pulsar 是音讯队列畛域的一匹黑马,其最大长处在于它提供了比 Apache Kafka 更简单明了、更强壮的一系列操作性能,反对地区复制和多租户。此外,相比传统的 Kafka、RocketMQ 等,Pulsar 更加适宜 IoT 的场景。

二、架构设计
2.1 整体架构

Apache Pulsar 和其余音讯零碎最基本的不同是采纳分层架构。
Apache Pulsar 集群由两层组成:无状态服务层:由一组接管和传递音讯的 Broker 组成有状态长久层:由一组 Apache BookKeeper 存储节点组成,可长久化地存储音讯。

图片.png

Pulsar 客户端不间接与存储层 Apache BookKeeper 交互。客户端也没有间接的 BookKeeper 拜访权限。这种隔离,为 Pulsar 实现平安的多租户对立身份验证模型提供了根底。

2.2 Broker

Broker 集群在 Apache Pulsar 中造成无状态服务层。Broker 不在本地存储任何音讯数据。Pulsar 主题的音讯,都被存储在分布式日志存储系统(Apache BookKeeper)中。

每个主题分区(Topic Partition)由 Pulsar 调配给某个 Broker,该 Broker 称为该主题分区的所有者。Pulsar 生产者和消费者连贯到主题分区的所有者 Broker,以向所有者代理发送音讯并生产音讯。

如果一个 Broker 产生故障,Pulsar 会主动将其领有的主题分区挪动到群集中残余的某一个可用 Broker 中。重点阐明:因为 Broker 是无状态的,因而当产生 Topic 的迁徙时,Pulsar 只是将所有权从一个 Broker 转移到另一个 Broker,并不会有任何数据复制产生,故障转移十分轻量。

下图显示了一个领有 4 个 Broker 的 Pulsar 集群,其中 4 个主题分区散布在 4 个 Broker 中。每个 Broker 领有并为一个主题分区提供音讯服务。
image.gif 图片.png

2.3 Bookeeper
Apache BookKeeper 是 Apache Pulsar 的长久化存储层。Apache Pulsar 中的每个主题分区实质上都是存储在 Apache BookKeeper 中的分布式日志。

每个分布式日志又被分为 Segment 分段。每个 Segment 分段作为 Apache BookKeeper 中的一个 Ledger,均匀分布并存储在 BookKeeper 群集中的多个 Bookie 中。

通过 Segment 分段的形式,主题分区中的音讯能够平均和均衡地散布在群集中的所有 Bookie 中。这意味着主题分区的大小不仅受一个节点容量的限度;相同,它能够扩大到整个 BookKeeper 集群的总容量。

上面的图阐明了一个分为 x 个 Segment 段的主题分区。每个 Segment 段存储 3 个正本。所有 Segment 都散布并存储在 4 个 Bookie 中。image.gif

图片.png

2.4 劣势
计算存储拆散的个性给 Pulsar 带来了许多个性
无限度的主题分区存储
无缝 Broker 故障复原无缝 Bookeeper 故障复原无缝集群扩大

无限度的主题分区存储
因为主题分区被宰割成 Segment 并在 Apache BookKeeper 中以分布式形式存储,因而主题分区的容量不受任何繁多节点容量的限度。主题分区能够扩大到整个 BookKeeper 集群的总容量,只需增加 Bookie 节点即可扩大集群容量。这是 Apache Pulsar 反对存储有限大小的流数据,并可能以高效,分布式形式解决数据的要害。

无缝 Broker 故障复原
下图阐明了 Broker 故障复原。本例中 Broker2 因某种原因(例如停电)而断开。Pulsar 检测到 Broker2 已敞开,并立刻将 Topic1-Part2 的所有权从 Broker2 转移到 Broker3。在 Pulsar 中数据存储和数据服务拆散,所以当代理 3 接管 Topic1-Part2 的所有权时,它不须要复制 Partiton 的数据。如果有新数据到来,它立刻附加并存储为 Topic1-Part2 中的 Segment x + 1。Segment x + 1 被散发并存储在 Bookie1, 2 和 4 上。因为它不须要从新复制数据,所以所有权转移立刻产生而不会就义主题分区的可用性。
图片.png

无缝 Bookeeper 故障复原
下图阐明了 Bookeeper 的故障复原。这里有一个磁盘故障导致存储在 bookie2 上的 Segment 4 被毁坏。Apache BookKeeper 后盾会检测到这个谬误并进行复制修复。

图片.png

BookKeeper 中的正本修复是 Segment 级别的多对多疾速修复,这比从新复制整个主题分区要精密,只有复制必须的数据。这意味着 Apache BookKeeper 能够从 bookie3 和 bookie4 读取 Segment4 中的音讯,并在 bookie1 处修复 Segment4。所有的正本修复都在后盾进行,对 Broker 和利用通明。

即便有 Bookie 节点出错的状况产生时,通过增加新的可用的 Bookie 来替换失败的 Bookie,所有 Broker 都能够持续承受写入,而不会就义主题分区的可用性。

无缝集群扩大
下图阐明了 Pulsar 集群扩大。当 Broker2 将音讯写入 Topic1-Part2 的 Segment X 时,将 Bookie X 和 Bookie Y 增加到集群中。Broker2 立刻发现新退出的 Bookies X 和 Y。而后 Broker 将尝试将 Segment X + 1 和 X + 2 的音讯存储到新增加的 Bookie 中。新减少的 Bookie 立即被应用起来,流量立刻减少,而不会从新复制任何数据。除了机架感知和区域感知策略之外,BookKeeper 还提供资源感知的搁置策略,以确保流量在群集中的所有存储节点之间保持平衡。图片.png

三、音讯模型
3.1 通用的音讯模型
音讯模型个别以下 3 个方面:

音讯生产:如何发送和生产音讯
音讯确认(ACK):如何确认音讯
音讯保留(Retention):音讯保留工夫,触发音讯删除的起因以及怎么删除
3.2 通用的生产模型
队列模型
队列模型次要是采纳无序或者共享的形式来生产音讯。通过队列模型,多个消费者能够从单个管道中接管音讯;当一条音讯从队列发送进去后,多个消费者中的只有一个(任何一个都有可能)接管和生产这条音讯。音讯零碎的具体实现决定了最终哪个消费者理论接管到音讯。

队列模型通常与无状态应用程序一起联合应用。无状态应用程序不关怀排序,但它们的确须要可能确认(ack)或删除单条音讯,以及尽可能地扩大生产并行性的能力。典型的基于队列模型的音讯零碎包含 RabbitMQ 和 RocketMQ。

流模型
流模型要求音讯的生产严格排序或独占音讯生产。对于一个管道,应用流式模型,始终只会有一个消费者应用和生产音讯。消费者依照音讯写入管道的确切程序接管从管道发送的音讯。

流模型通常与有状态应用程序相关联。有状态的应用程序更加关注音讯的程序及其状态。音讯的生产程序决定了有状态应用程序的状态。音讯的程序将影响利用程序处理逻辑的正确性。

3.3 Pulsar 音讯生产
Pulsar 形象出了对立的生产模型: producer-topic-subscription-consumerPulsar 的音讯模型既反对队列模型,也反对流模型

Topic 是用于发送音讯的通道。Topic 中的每条音讯,能够依据消费者的订阅需要,屡次被应用,每个订阅对应一个消费者组(Consumer Group)。每个 Topic 能够有不同的生产组。

消费者(consumer)被组合在一起以生产音讯,每个生产组是一个订阅(subscription)消费者能够领有不同的生产形式:独占(Exclusive),故障切换(Failover)或共享(Share)

Pulsar 通过这种模型,将队列模型和流模型这两种模型联合在了一起,提供了对立的 API 接口。这种模型,既不会影响音讯零碎的性能,也不会带来额定的开销,同时还为用户提供了更多灵活性,不便用户依据本人的理论场景来应用音讯零碎。

独占订阅(流模型)
独占模式,topic 只能被一个消费者订阅。如果多于一个消费者以同样形式去订阅主题,消费者将会收到谬误。下图中,只有 Consumer A- 0 能够生产 图片.png

容灾订阅(流模型)
容灾模式,多个消费者能够订阅同一个 topic,消费者按音讯者名称的字典序排列。第一个消费者被初始化为惟一接管音讯的消费者。这个消费者被称为主消费者(master consumer)。当主消费者断开时,所有的音讯(未被确认和后续进入的)将会被分发给下一个消费者。在下图中,Consumer-B- 0 是主消费者,如果 Consumer-B- 0 断开连接,Consumer-B- 1 会变成主消费者去接管音讯 图片.png

共享订阅(队列模型)
在共享(shared)或轮询 (round robin) 模式下,多个使用者能够订阅同一个 topic。音讯通过轮询形式分发给不同的消费者,并且每个音讯仅会被分发给一个消费者。当消费者断开连接,所有被发送给它,但没有被确认的音讯将被重新安排,分发给其它存活的消费者。在下图中,Consumer-C- 1 和 Consumer-C- 2 能够订阅该主题,然而 Consumer-C- 3 和其余消费者也能够订阅该主题。图片.png

3.4 Pulsar 音讯确认
当应用分布式音讯零碎时,可能会产生故障。比方在消费者从音讯零碎中的主题生产音讯的过程中,消费者和 Broker 都可能产生谬误。音讯确认(ACK)的目标就是保障当产生这样的故障后,消费者可能从上一次进行的中央复原生产,保障既不会失落音讯,也不会反复解决曾经 ACK 的音讯。

在 Pulsar 中,每个订阅中都应用一个专门的数据结构——游标(Cursor)来跟踪订阅中的每条音讯的 ACK 状态。每当消费者确认音讯时,游标都会更新。更新游标可确保消费者不会再次收到音讯。

Pulsar 提供两种音讯确认办法,单条确认(Individual Ack)和累积确认(Cumulative Ack)。通过累积确认,消费者只须要确认它收到的最初一条音讯。主题分区中的所有音讯(包含)提供音讯 ID 将被标记为已确认,并且不会再次传递给消费者。

Pulsar 能够反对音讯的单条确认,也就是选择性确认。消费者能够独自确认一条音讯。被确认后的音讯将不会被从新传递。下图阐明了单条确认和累积确认的差别(灰色框中的音讯被确认并且不会被从新传递)。在图的上半局部,它显示了累计确认的一个例子,M12 之前的音讯被标记为 acked。在图的下半局部,它显示了独自进行 acking 的示例。仅确认音讯 M7 和 M12 – 在消费者失败的状况下,除了 M7 和 M12 之外,其余所有音讯将被从新传送。图片.png

独占订阅或容灾订阅的消费者可能对音讯进行单条确认和累积确认;共享订阅的消费者只容许对音讯进行单条确认。单条确认音讯的能力为解决消费者故障提供了更好的体验。对于某些利用来说,解决一条音讯可能须要很长时间或者十分低廉,避免从新传送曾经确认的音讯十分重要。

游标(Cursor)由 Broker 来治理,利用 BookKeeper 的 Ledger 提供存储。

Apache Pulsar 提供了灵便的音讯生产订阅类型和音讯确认办法,通过简略的对立的 API,就能够反对各种音讯和流的应用场景。

3.5 Pulsar 音讯保留
在音讯被确认后,Pulsar 的 Broker 会更新对应的游标。当 Topic 外面中的一条音讯,被所有的订阅都确认 ack 后,能力删除这条音讯。Pulsar 还容许通过设置保留工夫,将音讯保留更长时间,即便所有订阅曾经确认生产了它们。

下图阐明了如何在有 2 个订阅的主题中保留音讯。订阅 A 在 M6 和订阅 B 曾经耗费了 M10 之前的所有音讯之前曾经耗费了所有音讯。这意味着 M6 之前的所有音讯(灰色框中)都能够平安删除。订阅 A 仍未应用 M6 和 M9 之间的音讯,无奈删除它们。如果主题配置了音讯保留期,则音讯 M0 到 M5 将在配置的时间段内放弃不变,即便 A 和 B 曾经确认生产了它们。图片.png

在音讯保留策略中,Pulsar 还反对音讯生存工夫(TTL)。如果音讯未在配置的 TTL 时间段内被任何消费者应用,则音讯将主动标记为已确认。音讯保留期音讯 TTL 之间的区别在于:音讯保留期作用于标记为已确认并设置为已删除的音讯,而 TTL 作用于未 ack 的音讯。下面的图例中阐明了 Pulsar 中的 TTL。例如,如果订阅 B 没有流动消费者,则在配置的 TTL 时间段过后,音讯 M10 将主动标记为已确认,即便没有消费者理论读取该音讯。

四、为什么 Pulsar 更适宜 IoT 场景
4.1 海量 Topic
Pulsar 计算存储拆散的架构,使得 Pulsar 能够反对百万级别 Topic 数量的扩大,同时还能始终保持良好的性能。

Topic 的伸缩性取决于它的外部组织和存储形式。Pulsar 的数据保留在 BookKeeper 服务器上,处于写状态的不同 Topic 的音讯,在内存中排序,最终聚合保留到大文件中,在 Bookie 中须要更少的文件句柄。另一方面 Bookie 的 IO 更少依赖于文件系统的 Pagecache,Pulsar 也因而可能反对大量的主题。

这是一个极大的晋升,相比之下,Kafka 计算存储未分离,Topic 多了之后会影响其程序 IO,性能会呈现比较严重的降落。

IoT 场景的 Topic 数量是数以亿计的,Pulsar 能反对海量 Topic 的能力恰好满足了 IoT 场景的需要

4.2 租户隔离
Pulsar 通过租户和命名空间这两个要害概念反对多租户,Pulsar 的多租户性质次要体现在 topic 的 URL 中

{persistent|non-persistent}://tenant/namespace/topic

多租户是 IoT 场景的一个根本需要,Pulsar 通过在 topic 中附加命名空间达到了租户隔离的成果。

4.3 音讯 TTL
Pulsar 能够给未被确认的音讯设置存活时长(TTL),尽管 TTL 的设置是针对整个 namespace 起效的,无奈针对单个 Topic,但能够满足 IoT 场景下不同用户个性化指定 TTL 的要求

五、参考文献
https://streaml.io/blog/pulsa…

https://pulsar.apache.org/zh-CN/

原文链接:http://click.aliyun.com/m/100…

本文为阿里云原创内容,未经容许不得转载。

退出移动版