消息队列 pulsar 架构学习

转自:comparing-pulsar-and-kafka-how-a-segment-based-architecture-delivers-better-performance-scalability-and-resilience

Pulsar 基础架构

一个pulsar 集群由两层构成:

  • 无状态的服务层,由多个brokers 组成,负责发送和接受消息
  • 有状态的持久化层,由多个BookKeeper 存储节点(bookies )来持久化消息

一个典型的pulsar 架构如图:

消息队列 pulsar 架构学习_第1张图片

应用通过pulsar客户端访问brokers 以生产或消费消息,客户端不直接与BookKeeper 或者 Zookeeper 交互,这种良好的隔离简化了租户下的鉴权。

 

Brokers

brokers组成了pulsar的无状态层,“无状态”是因为brokers 不在本地保存消息,消息都保存在分布式日志系统BookKeeper.

每个  topic partition 由 pulsar 分配给一个broker,该broker 成为前者的 owner broker,客户端通过与该broker建立连接来发送或消费消息。

如果这个broker 挂了,pulsar自动将其分配到的topic partition 重新派给集群中剩余可用的broker。此过程只是将topic partition 的所有权进行了转移,不涉及数据拷贝。

下图展示了4个 broker 管理4个  topic partition 的情况

消息队列 pulsar 架构学习_第2张图片

 

Bookies

BookKeeper  是 pulsar 的持久层,每个 topic partition 本质上是存在BookKeeper  的分布式日志。

 

分布式日志被切分成多个段,每段存放到多个bookies(BookKeeper 的存储单元)。

当前段写入时长到达配置的时长、或者当前段大小达到配置的阈值,或topic partition 的所有权进行了变更,都会产生新的段。

通过分段,topic partition 的消息可以均衡的分布与所有bookies,这意味着一个topic partition的容量不局限于一个节点,甚至可以扩展至整个BookKeeper 支持的最大容量。

下图展示了一个topic partition 被分为x段,每一段存3个副本,所有段及其副本分配在4个broker

消息队列 pulsar 架构学习_第3张图片

 

段式存储(Segment-Centric Storage)

Pulsar 的主要两个关键设计在于分层架构和段式存储,他们为pulsar 带来了以下便利:

  • 无限制的 topic partition 存储
  • 任意伸缩而不需要数据再均衡 
    • 无缝的 broker 故障恢复
    • 无缝的集群扩容
    • 无缝的 bookie 部长恢复
  • 独立伸缩性

无限制 Topic Partition 存储

因为 topic partition 被分割为多个段且在 BookKeeper 中分布式存放,一个 topic partition 的容量就不受限于容量最小的bookie 节点,甚至可以支持到整个BookKeeper 集群的容量。集群扩容也只需要添加节点即可,这使得pulsar 可以存放随时间无限增长的数据,并以高效、分布式的方式处理数据,而其本质就是分布式日志存储。

 

无需数据再平衡(rebalancing)的即时扩容

因为消息服务和存储在两个独立的层,将一个 topic partition 从过一个broker 迁移到另一个broker 可以瞬间完整且无需数据rebalance(从前一个broker拷贝数据到后一个)。这个特性对于集群扩容、broker和bookie的崩溃快速响应十分关键。下面用图解释:

Broker 无缝崩溃恢复

下图展示了pulsar 如何处理broker崩溃。Broker 2 因某种原因(如电源耗尽)崩溃了,pulsar 检测到Broker 2 下线,立即将Topic1-Part2 的所有权从Broker2 转移至Broker3.

当broker3接管Topic1-Part2 时,不需要拷贝第1段到第4段数据。新写入的数据直接添加并存放于 Topic1-Part2 新的段x+1(上面提到段所有权变更时会产生新的段)。第x+1段分布式存放于bookies 1, 2 ,4

因为不需要数据拷贝,topic partition的所有权变更几乎瞬间完成,不需要牺牲 topic partitions 的可用性(无缝)。

消息队列 pulsar 架构学习_第4张图片

集群无缝扩容

下图展示了 pulsar 集群如何扩容。

当broker 2 往 Topic1-Part2 第 X段写数据时,bookies X 和Y添加到了集群,broker2会立即发现,并尝试将新写入X+1 段和X+2段的数据写入新的bookie。新的bookie 瞬间被利用起来,也不涉及数据拷贝。

BookKeeper 提供了资源感知(resource-aware)的放置策略,外加机架感知(rack-aware)和区域感知( region-aware)策略,以保证数据能均衡路由到所有节点,防止新的bookie 过于空闲。(BookKeeper  决定了新的段放置在那个bookie,新加入的bookie 也会加以利用,上游无感知)

消息队列 pulsar 架构学习_第5张图片

Bookie 无缝崩溃恢复

下图展示了pulsar 如何处理bookie 或磁盘崩溃。

这里bookie 2的第4段发生了磁盘崩溃。BookKeeper 检测到之后发起副本修复(replica repair)。

副本修复是段层面的多对多的快速修复,相比与整个topic partition 拷贝而言操作粒度更好。BookKeeper 还可以从bookie3 和bookie4读取到第4段数据,并在bookie1复原第4段数据。

副本修复在后台进行,所有brokers 可以继续接受写请求,不需要通过用正常的bookie 替换崩溃的bookie 从而牺牲topic partitions 的可用性

消息队列 pulsar 架构学习_第6张图片

独立可扩展性

因为服务层与持久化层分开,pulsar 可以对两个层分别进行扩容。这使得容量评估更高效:

  • 当需要支持更多消费者/生产者时,仅需添加更多的brokers。topic partition 会立即在这些broker之中进行分配,部分topic partition的所有权转移给新加入的broker
  • 当需要更多存储来将消息保存更久些时,仅需要添加bookie节点。依靠框架智能感知的数据放置策略,请求会自动路由到新的bookie

更多细节详见 Why BookKeeper? 

 

与 Kafka 对比

kafka 和 pulsar 有着相似的消息概念,客户端通过topic 与系统交互。每个topic 分成多个partition。

然而,两者主要区别在于kafka 是以分区为中心(partition-centric )的生产-消费系统,pulsar 是以分段为中心(segment-centric)的系统。

消息队列 pulsar 架构学习_第7张图片

上图展示了分区为中心和分段为中心的系统的区别,kafka 中partition 只能存储在一个节点并复制到另外的节点,因此容量受限于最小的节点。

这意味着扩容需要partition再分配,即需要将整个partition 的数据和路由都拷贝到新加的broker中。重复拷贝数据开销较大且容易出错,消耗更多网络带宽与io。操作时必须小心谨慎,否则很容易把生产环境搞垮。

分区为中心的系统的partition数据拷贝不仅发生在扩容时,很多其他场景会触发数据拷贝,例如副本下线、磁盘挂了、机器宕机。此时partition不可用,直到数据拷贝完成。
例如partition 配置成需存储3个副本,即使丢了其中一个,也需要拷贝整个partition。这种限制通常会被忽略除非亲身体验服务下线,因为大多数使用场景是仅仅用做短期缓存。

pulsar 中,一个partition 被分成多个段,按照易扩展方式分布于集群中。因为是基于分段的所以扩容时不需要数据重新分配,这得益于BookKeeper 的可扩展分段分布式日志存储。当新的节点或partition 加入集群时,流量会迅速补充到新的节点,不需要数据拷贝。
借助分布式日志存储,pulsar 可以最大化分段分布策略的效益以获取较高的读写可用性。当设置topic partition副本数为2时,只要2个bookie 在线就能保证可写入,在topic partition 集群中有1个broker 在线就能保证可读。

 

 

你可能感兴趣的:(pulsar)