在本文中,我们将介绍ApachePulsar的设计,以便更好地设计故障场景。这篇文章不是为那些想了解如何使用ApachePulsar的人写的,而是为那些想了解它是如何工作的人写的。我一直在努力以一种简单易懂的方式对其架构进行清晰的概述。
主要的声明包括:
- 保证不会丢失消息(如果采用了建议的配置,并且您的整个数据中心不会被烧毁)
- 强排序保证
- 可预测的读写延迟
Apache Pulsar选择一致性而不是可用性,其姊妹项目BookKeeper和ZooKeeper也是如此。尽一切努力使其具有很强的一致性。
我们将看看Pulsar的设计,看看这些说法是否有效。
多层抽象
ApachePulsar具有主题和订阅的高级概念,最低级别的数据存储在二进制文件中,这些二进制文件将分布在多台服务器上的多个主题的数据交织在一起。中间是无数的细节和运动部件。我个人认为,如果我将Pulsar架构划分为不同的抽象层,那么理解它就更容易了,所以这就是我在本文中要做的。
让我们沿着层层往下走。
第1层-主题、订阅和游标
这篇文章不是关于可以使用Apache Pulsar构建的消息传递体系结构的。我们将只介绍主题、订阅和游标的基本内容,但不会深入了解Pulsar支持的更广泛的消息传递模式。
消息存储在主题中。从逻辑上讲,主题是一个日志结构,每条消息都有一个偏移量。Apache Pulsar使用术语游标来描述偏移量的跟踪。制作人将他们的信息发送到给定的主题,Pulsar保证,一旦信息被确认,它就不会丢失(除了一些超级糟糕的灾难或糟糕的配置)。
消费者通过订阅使用来自主题的消息。订阅是一个逻辑实体,它跟踪光标(当前使用者偏移量),并根据订阅类型提供一些额外的保证:
- 独家订阅-一次只有一个消费者可以通过订阅阅读主题
- 共享订阅-竞争消费者可以通过同一订阅同时阅读主题。
- 故障转移订阅-用户的活动/备份模式。如果活动consumer消费者死亡,则备份将接管。但从来没有两个活跃的消费者同时存在。
一个主题可以有多个附加订阅。订阅不包含数据,只包含元数据和光标。
Pulsar提供了排队和日志语义,允许消费者将Pulsar主题视为在消费者确认后删除消息的队列,或者消费者可以在需要时回放光标的日志。下面的存储模型是相同的-一个日志。
如果未对主题(通过其命名空间)设置数据保留策略,则在附加订阅的所有游标都通过其偏移量后,将删除消息。也就是说,邮件已在附加到该主题的所有订阅上得到确认。
但是,如果存在覆盖主题的数据保留策略,则消息在通过策略边界(主题大小、主题中的时间)后将被删除。
也可以发送过期的消息。如果这些消息在未确认的情况下超过TTL,则会将其删除。这意味着可以在任何消费者有机会阅读它们之前将其删除。过期只适用于未确认的消息,因此更适合于事物的排队语义方面。
TTL分别应用于每个订阅,这意味着“删除”是一种逻辑删除。实际删除将根据其他订阅和任何数据保留策略中发生的情况在以后进行。
消费者一个接一个地或累积地确认他们的信息。累积确认将更好地提高吞吐量,但会在使用者失败后引入重复的消息处理。但是,累积确认不适用于共享订阅,因为确认基于偏移量。但是,使用者API允许批处理确认,这些批处理确认最终将得到相同数量的确认,但RPC调用更少。这可以提高共享订阅上竞争消费者的吞吐量。
最后,还有一些与Kafka主题类似的分区主题。不同的是,Pulsar中的分区也是主题。就像kafka一样,生产者可以循环发送消息,使用散列算法或显式选择分区。
这是对高级概念的旋风式介绍,我们现在将深入探讨。请记住,这不是从10000英尺的高度对Apache Pulsar的入门介绍,而是从1000英尺的高度看它是如何在下面工作的。
第2层-逻辑存储模型
现在Apache BookKeeper进入了现场。我将在Apache Pulsar的上下文中讨论BookKeeper,尽管BookKeeper是一个通用的日志存储解决方案。
首先,Apache BookKeeper跨节点集群存储数据。每个BookKeeper节点称为一个BookKeeper。其次,Pulsar和BookKeeper都使用ApacheZooKeeper来存储元数据和监视节点健康状况。
一个主题实际上是一系列Ledgers。Ledger本身就是一个日志。因此,我们从一系列子日志(分类账)组成一个父日志(主题)。
Ledger附加到主题,entries(消息或消息组)附加到Ledgers。Ledgers一旦关闭,就不可更改。Ledgers是作为一个整体删除的,也就是说,我们不能删除单个条目,而是作为一个整体删除Ledgers。
Ledgers本身也被分解成碎片。片段是BookKeeper集群中最小的分布单元(根据您的观点,条带化可能会使该声明无效)。
主题是一个Pulsar概念。