一、Pulsar概述
Apache Pulsar是Apache软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用计算与存储分离架构设计,支持多租户、持久化存储、多机房跨区域数据复制,具有强一致性、高吞吐、低延时及高可扩展性等流数据存储特性,被看作是云原生时代实时消息流传输、存储和计算最佳解决方案。
Pulsar是一个pub-sub (发布-订阅)模型的消息队列系统。
(一)Pulsar架构
Pulsar由Producer、Consumer、多个Broker、一个BookKeeper集群、一个Zookeeper集群构成,具体如下图所示。
-
Producer:数据生成者,即发送消息的一方。生产者负责创建消息,将其投递到Pulsar中。
-
Consumer:数据消费者,即接收消息的一方。消费者连接到 Pulsar 并接收消息,进行相应的业务处理。
-
Broker:无状态的服务层,负责接收消息、传递消息、集群负载均衡等操作,Broker不会持久化保存元数据。
-
BookKeeper:有状态的持久层,包含多个Bookie,负责持久化地存储消息。
-
ZooKeeper:存储Pulsar、BookKeeper的元数据,集群配置等信息,负责集群间的协调(例如:Topic与Broker的关系)、服务发现等。
从Pulsar的架构图上可以看出,Pulsar在架构设计上采用了计算与存储分离的模式,发布/订阅相关的计算逻辑在Broker上完成,而数据的持久化存储交由BookKeeper去实现。
-
Broker扩展
在Pulsar中Broker是无状态的,当需要支持更多的消费者或生产者时,可以简单地添加更多的Broker节点来满足业务需求。Pulsar支持自动的分区负载均衡,在Broker节点的资源使用率达到阈值时,会将负载迁移到负载较低的Broker节点,这个过程中分区也将在多个Broker节点中做平衡迁移,一些分区的所有权会转移到新的Broker节点。在后面Bundle小节会具体介绍这部分的实现。
-
Bookie扩展
存储层的扩容,通过增加Bookie节点来实现。在BooKie扩容的阶段,由于分片机制,整个过程不会涉及到不必要的数据搬迁,即不需要将旧数据从现有存储节点重新复制到新存储节点。在后续的Bookkeeper小节中会具体介绍。
(二)Topic
和其他消息队列类似,Pulsar中也有Topic。Topic即在生产者与消费者中传输消息的通道。消息可以以Topic为单位进行归类,生产者负责将消息发送到特定的Topic,而消费者指定特定的Topic进行消费。
-
分区Topic(Topic-Partition)
Pulsar的Topic可以分为非分区Topic和分区Topic。
普通的Topic仅仅被保存在单个Broker中,这限制了Topic的最大吞吐量。分区Topic是一种特殊类型的主题,支持被多个Broker处理,从而实现更高的吞吐量。
针对一个Topic,可以设置多个Topic分区来提高Topic的吞吐量。每个Topic Partition由Pulsar分配给某个Broker,该Broker称为该Topic Partition的所有者。生成者和消费者会与每个Topic分区的Broker创建链接,发送消息并消费消息。
如下图所示,Topic1有Partition1、Partition2、Partition3、Partition4、Partition5五个分区,Partition1和Partition4由Broker1处理,Partition2和Partition5由Broker2处理,Partition3由Broker3处理。
从Pulsar社区版的golang-sdk可以看出,客户端的Producer和Consumer在初始化的时候,都会与每一个Topic-Partition创建链接,并且会监听是否有新的Partition,以创建新的链接。
-
非持久Topic
默认情况下,Pulsar会保存所有没确认的消息到BookKeeper中。持久Topic的消息在Broker重启或者Consumer出现问题时保存下来。
除了持久Topic,Pulsar也支持非持久Topic。这些Topic的消息只存在于内存中,不会存储到磁盘。
因为Broker不会对消息进行持久化存储,当Producer将消息发送到Broker时,Broker可以立即将ack返回给Producer,所以非持久Topic的消息传递会比持久Topic的消息传递更快一些。相对的,当Broker因为一些原因宕机、重启后,非持久Topic的消息都会消失,订阅者将无法收到这些消息。
-
重试Topic
由于业务逻辑处理出现异常,消息一般需要被重新消费。Pulsar支持生产者同时将消息发送到普通的Topic和重试Topic,并指定允许延时和最大重试次数。当配置了允许消费者自动重试时,如果消息没有被消费成功,会被保存到重试Topic中,并在指定延时时间后,重新被消费。
-
死信Topic
当Consumer消费消息出错时,可以通过配置重试Topic对消息进行重试,但是,如果当消息超过了最大的重试次数仍处理失败时,该怎么办呢?Pulsar提供了死信Topic,通过配置deadLetterTopic,当消息达到最大重试次数的时候,Pulsar会将消息推送到死信Topic中进行保存。
(三)订阅(subscription)
通过订阅的方式,我们可以指定消息如何投递给消费者。
-
订阅类型(Subscription type)
Pulsar支持独占(Exclusive)、灾备(Failover)、共享(Shared)、Key_Shared这四种订阅类型。
独占(Exclusive)SinglePartition
Exclusive下,只允许Subscription存在一个消费者,如果多个消费者使用同一个订阅名称去订阅同一个Topic,则会报错。如下图,只有Consumer A-0可以消费数据。
灾备(Failover)
Failover下,一个Subscription中可以有多个消费者,但只有Master Consumer可以消费数据。当Master Consumer断开连接