Dawn's Blogs

分享技术 记录成长

0%

Pulsar消息队列(1)简介

Apache Pulsar是一个支持多租户的、高性能的、分布式多租户消息系统,最初由雅虎开发,现在是Apache软件基金会的顶级项目。 Pulsar提供非常低的消息发布和端到端的延迟、保障消息可靠传递零丢失。

分布式消息系统

Pulsar 是基于段的分布式消息队列。

一般的消息系统在逻辑上都可分为服务层和存储层两层:

  • 服务层:直接与消息的生产者和消费者交互,接收传入的消息并将消息路由到一个或多个目的地。服务层通过支持的消息协议进行通讯,例如AMQP。服务层在消息协议转换上依赖CPU,在通信上依赖网络带宽。
  • 存储层:负责消息的存储。存储层与服务层交互提供服务层请求的消息,存储层保持消息的正确顺序。存储层严重依赖硬盘来存储消息。

分布式消息系统与传统单点消息系统在架构上的主要差别在于存储层的设计方式。在分布式消息传递系统中,数据分布在集群中的多台机器上,允许在单个主题中保留超过单个机器存储容量的消息。分布式消息系统存储层的关键架构抽象是 write-ahead-log,它将存储的消息看成是单个仅追加的数据结构。 对于分布式消息系统,当新消息发布到主题时,从逻辑的角度来看,消息将被追加到日志的末尾;从物理的角度来看,消息可能写入集群中的任何服务器。

partion-based-msg.png

分布式消息系统的好处是将负载分散到多台机器上,可以提高消息的生产和消费的吞吐量,每台服务器都有自己硬盘和写入路径,将提供更好的写入速率。 在分布式消息系统集群中分布消息数据时,有两种不同的方法: 基于分区(Partion-based)和基于段(Segment-based)

基于分区

Kafka 采用的是基于分区的消息存储架构。

在基于分区的消息存储结构中,Topic 被划分为固定数量的分区,发布到 Topic 中的数据均匀的分布在分区中,同时为了确保数据冗余,每个分区会被复制到不同的节点

Topic 中消息的总存储量为 Topic 的分区数乘以分区的大小,如果达到这个限制,需要向集群添加更多的节点同时增加 Topic 的分区数量才能继续向分区中添加数据,增加分区的数量还需要执行重新平衡,这是一个十分复杂和耗时的过程。

在基于分区的消息存储结构的分布式消息系统中,一般在创建 Topic 的时候需要预先确定分区数量,但这样做有一些缺点,因为单个分区只会存储在集群中单个集群节点上,因此单个分区的大小就受限于该节点上的硬盘空间大小,由于 Topic 中的数据均匀分布在所有分区中,所以如果集群节点的硬盘容量不一样的话,那么 Topic 的每个分区的大小将限制为最小硬盘容量的节点。当 Topic 达到容量限制后,唯一能做的就是增加 Topic 的分区数量,但这个扩容的过程包括重新平衡整个 Topic,Topic 中的数据将被重新分布到该 Topic 的所有分区中,平衡数据的过程十分消耗网络带宽和磁盘 I/O

kafka-partitions

基于段

Pulsar 采用的是基于段的消息存储结构。

Pulsar 中服务层合存储层都是无状态的,可以任意的进行水平扩容。引入 Zookeeper 集群,用于集群级别的配置和协调,Zookeeper 中存储 Pulsar 集群的所有元数据(例如 Topic 元数据、Broker 负载数据等等)

Pulsar 依赖 Apache BookKeeper 项目来实现消息的持久存储,BookKeeper 的逻辑存储模型是基于无限流记录作为顺序日志存储的概念。

在BookKeeper中,每个日志被分解成更小的数据块,称为段(Segament),这些数据块又由多个日志条目组成。然后,为了实现冗余和扩展,这些段会在存储层中被称为 bookies 的多个节点上写入。可以将段放在集群节点具有足够硬盘容量的任何位置,当没有足够的空间用于存储新的段时,可以方便地添加节点并立即存储数据。基于段的存储架构的优点在于可以实现真正的水平伸缩,段可以被无限创建并存储在任何位置。

pulsar-segaments