云原生分布式消息流平台-Apache Pulsar
2021-02-05 21:59:21 阿炯

Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体。Pulsar由Yahoo在2013年创建,并于2016年捐赠给Apache基金会。最初在 Yahoo 内部开发和部署,支持 Yahoo 应用服务平台 140 万个主题,日处理超过 1000 亿条消息。2018 年成为 Apache 软件基金会顶级项目,采用java开发并在Apache协议下授权。

Apache Pulsar is a cloud-native, distributed messaging and streaming platform originally created at Yahoo! and now a top-level Apache Software Foundation project.


Yahoo,Verizon,Twitter等公司在生产中使用它来处理数百万条消息,它具有许多功能,并且非常灵活。它声称比Kafka更快,因此运行成本更低。旨在解决Kafka的大部分难题,使其更易于扩展。Pulsar非常灵活,它可以像Kafka这样的分布式日志,也可以像RabbitMQ这样的纯消息传递系统。它具有多种类型的订阅,几种交付保证,保留策略以及几种处理模式演变的方法。作为下一代云原生分布式消息流平台,支持多租户、持久化存储、多机房跨区域数据复制,具有强一致性、高吞吐以及低延时的高可扩展流数据存储特性,内置诸多其他系统商业版本才有的特性,是云原生时代解决实时消息流数据传输、存储和计算的最佳解决方案。

Apache Pulsar 提供了统一的消费模型,支持Stream如Kafka和Queue如RabbitMQ两种消费模型,支持 exclusive、failover 和 shared 三种消费模式。同时,Pulsar 提供和 Kafka 兼容的 API,以及 Kafka-On-PulsarKoP 组件来兼容 Kafka 的应用程序,KoP 在 Pulsar Broker 中解析 Kafka 协议,用户不用改动客户端的任何 Kafka 代码就能直接使用 Pulsar。

特性

由于内置了多租户,因此不同的团队可以使用相同的集群并将其隔离,这解决了许多管理难题。它支持隔离,身份验证,授权和配额。
多层体系结构,Pulsar将所有主题数据存储在由Apache BookKeeper支持的专业数据层中,作为数据分类帐。存储和消息传递的分离解决了扩展,重新平衡和维护集群的许多问题。 它还提高了可靠性,几乎不可能丢失数据。另外在读取数据时,可以直接连接到Bookeeper,而不会影响实时摄取。例如,可以使用Presto对主题执行SQL查询,类似于KSQL,但请放心,这不会影响实时数据处理。
虚拟主题。由于采用n层体系结构,因此对主题的数量没有限制,主题及其存储是分离的。还可以创建非持久性主题。
N层存储。Kafka的一个问题是,存储可能变得昂贵。 因此它很少用于存储"冷"数据,并且消息经常被删除。并且仍然向客户展示透明视图;客户端可以从时间开始读取,就像所有消息都存在于日志中一样。
Pulsar函数。易于部署,轻量级计算过程,对开发人员友好的API,无需运行自己的流处理引擎(如Kafka)。
安全性:它具有内置的代理,多租户安全性,可插入身份验证等等。
快速重新平衡。 分区分为易于重新平衡的段。
服务器端重复数据删除和无效字段。无需在客户端中执行此操作,也可以在压缩期间执行重复数据删除。
内置架构注册表。支持多种策略,非常易于使用。
地理复制和内置发现。将群集复制到多个区域非常容易。
集成的负载均衡器和Prometheus指标。
多重集成,Kafka,RabbitMQ等。
支持许多编程语言,例如GoLang,Java,Scala,Node,Python…
客户端不需要知道分片和数据分区,这是在服务器端透明进行的。


目前Apache Pulsar已经应用部署在国内外众多大型互联网公司和传统行业公司,案例分布在人工智能、金融、电信运营商、直播与短视频、物联网、零售与电子商务、在线教育等多个行业,如美国有线电视网络巨头Comcast、腾讯、中国电信、中国移动、BIGO、VIPKID 等。Apache Pulsar 项目原生核心贡献者已组成创业公司 StreamNative,进一步为 Apache Pulsar 提供更好的企业级服务支持与生态建设。



优势

与Kafka相比的主要优势:
更多功能:Pulsar函数,多租户,架构注册表,n层存储,多种使用模式和持久性模式等。
更大的灵活性:3种订阅类型(独占,共享和故障转移),您可以在一个订阅上收听多个主题。持久性选项:非持久(快速),持久,压缩(每个消息仅最后一个键)。可以选择交付保证,它具有服务器端重复数据删除和无效字样。许多保留政策和TTL。
无需提前定义扩展需求。
支持排队和流媒体。 因此它可以像RabbitMQ或Kafka。
由于存储与代理分离,因此扩展性更好。重新平衡更快,更可靠。
易于操作:得益于去耦和n层存储。管理员REST API也很棒。
与Presto的SQL集成,可直接查询存储而不会影响代理。
借助n层自动存储选项,可以更便宜地存储。
更快:许多基准测试在各种情况下都表现出更好的性能。Pulsar声称具有较低的延迟和更好的扩展功能。但是这正受到Confluent的挑战,因此请带着盐味做,并自己制定基准。
Pulsar Functions将无服务器计算带到您的消息传递平台。
集成架构注册表支持轻松的架构演变
集成的负载平衡器和Prometheus指标。
地理复制效果更好,更易于设置。Pulsar还内置了发现能力。
可以创建的主题数量没有限制。
与Kafka兼容,易于集成。

问题

Pulsar并不完美,Kafka之所以流行是有原因的,它做一件事并且做得很好。Pulsar试图解决太多领域,但没有超越任何一个领域。让我们总结一下Pulsar的一些问题:
受欢迎程度:Pulsar不那么受欢迎。它缺乏支持,文档和实际使用情况。对于大型组织而言,这是一个主要问题。
由于n层体系结构,它需要更多组件:Bookkeeper。
在平台内没有对流应用程序的适当支持。 Pulsar函数与Kafka Streams不同,它们更简单,并且不用于实时流处理。 您无法进行有状态处理。
与Kafka相比,插件和客户端更少。此外,掌握Pulsar技能的人较少,因此需要在内部学习。
它在云中的支持较少。 Confluent具有托管云产品。

Confluent在Pulsar和Kafka之间进行了比较,可以在其中进行更多的详细说明。博客上还回答了有关Kafka与Pulsar的一些问题,但请注意,这些问题可能有偏见。

使用案例

Pulsar可用于广泛的用例:
发布/订阅队列消息传递
分布式日志
事件源壁架,用于永久性事件存储
微服务
SQL分析
无服务器功能

什么时候应该考虑Pulsar
需要像RabbitMQ这样的队列,也需要像Kafka这样的流处理程序。
需要简单的地理复制。
多租户是必须具备的,并且想确保每个团队的访问权限。
需要将所有消息保留很长时间,并且不想将其卸载到另一个存储中。
性能对你至关重要,基准测试表明Pulsar提供了更低的延迟和更高的吞吐量。
在本地运行,没有设置Kafka的经验,但具有Hadoop经验。

请注意,如果在云中,请考虑基于云的解决方案。云提供商拥有涵盖某些用例的不同服务。例如,对于队列消息传递,云提供商提供了许多服务,例如Google pub / sub。对于分布式日志,有Confluent云或AWS Kinesis。云提供商还提供了非常好的安全性。Pulsar的优势在于可以在一个平台上提供许多功能。一些团队可能将其用作微服务的消息传递系统,而另一些团队则将其用作数据处理的分布式日志。

在将Pulsar纳入组织之前,需要进行分析,进行基准测试,研究并编写概念证明。从小处着手,在从Kafka迁移之前进行概念验证,并在决定进行完全迁移之前先评估影响。

技术概览

Apache Pulsar 是一个多租户、高性能的服务间消息传输解决方案,数据持久化依赖 Apache BookKeeper 实现,支持多租户、低延时、读写分离、跨地域复制、快速扩容、灵活容错等特性。本节将从以下几个方面为大家介绍 Apache Pulsar 的设计原理和特性,转自腾讯云中间件的博客空间,主要分为4个小单元。
1、整体架构
2、架构设计的优势
3、Pulsar 特性
4、小结

整体架构

存储计算分离

Apache Pulsar 是 Pub/Sub 模型的消息系统,并且从设计上做了存储和计算的分离,如图一所示。



图一 Pulsar 架构

Apache Pulsar 主要包括 Broker, Apache BookKeeper, Producer, Consumer 等组件。

Broker:无状态服务层,负责接收和传递消息,集群负载均衡等工作,Broker 不会持久化保存元数据,因此可以快速的上、下线。
Apache BookKeeper:有状态持久层,由一组名为 Bookie 的存储节点组成,持久化地存储消息。
Producer :数据生产者,负责发布数据到 Topic。
Consumer:数据消费者,负责从 Topic 订阅数据。

除了上述的组件之外,Apache Pulsar 还依赖 Zookeeper 作为元数据存储。与传统的消息系统相比,Apache Pulsar 在架构设计上采用了计算与存储分离的模式,Pub/Sub 相关的计算逻辑在 Broker 上完成,数据存储在 Apache BookKeeper 的 Bookie 节点上。

分片存储

除了存储、计算解耦分离的设计之外,Apache Pulsar 在存储设计上也不同于传统 MQ 的分区数据本地存储的模式,采用的是分片存储的模式,存储粒度比分区更细化、存储负载更均衡。Apache Pulsar 中的每个 Topic 分区本质上都是存储在 Apache BookKeeper 中的分布式日志。Topic 可以有多个分区,分区数据持久化时,分区是逻辑上的概念,实际存储的单位是分片(Segment)的,如图二,一个分区 Topic1-Part2 的数据由多个 Segment 组成, 每个 Segment 作为 Apache BookKeeper 中的一个 Ledger,均匀分布并存储在 Apache BookKeeper 群集中的多个 Bookie 节点中, 每个 Segment 具有 3 个副本。



图二 Pulsar 分片存储

下面可以通过图三来看分区和分片存储的区别。



图三 分片存储和分区存储

架构设计的优势

Apache Pulsar 计算与存储分离的架构,以及分片存储的设计为 Apache Pulsar 带来了相比于传统基于分区存储 MQ 的一些优势:
Broker 和 Bookie 相互独立,方便实现独立的扩展以及独立的容错。
Broker 无状态,便于快速上、下线,更加适合于云原生场景。
分区存储不受限于单个节点存储容量。
分区数据分布均匀。
...

可扩展性

由于消息服务层和持久存储层是分开的,因此 Apache Pulsar 可以独立地扩展存储层和服务层。

Broker 扩展

在 Pulsar 中 Broker 是无状态的,可以通过增加节点的方式实现快速扩容。当需要支持更多的消费者或生产者时,可以简单地添加更多的 Broker 节点来满足业务需求。Pulsar 支持自动的分区负载均衡,在 Broker 节点的资源使用率达到阈值时,会将负载迁移到负载较低的 Broker 节点,这个过程中分区也将在多个 Broker 节点中做平衡迁移,一些分区的所有权会转移到新的 Broker 节点。

Bookie 扩展

存储层的扩容,通过增加 Bookie 节点来实现。通过资源感知和数据放置策略,流量将自动切换到新的 Bookie 节点中,整个过程不会涉及到不必要的数据搬迁,即不需要将旧数据从现有存储节点重新复制到新存储节点。



图四 Bookie 扩容

如图四所示,起始状态有四个存储节点,Bookie1, Bookie2, Bookie3, Bookie4,以 Topic1-Part2 为例,当这个分区的最新的存储分片是 SegmentX 时,对存储层扩容,添加了新的 Bookie 节点,BookieX,BookieY,那么在存储分片滚动之后,新生成的存储分片, SegmentX+1,SegmentX+2,会优先选择新的 Bookie 节点(BookieX,BookieY)来保存数据。

容错

得益于计算与存储分离以及分片存储的设计,Pulsar 可以实现独立、灵活的容错。

Broker 容错

当 Broker 节点失败时, 以图五为例,当存储分片滚动到 SegmentX 时,Broker2 节点失败,此时生产者和消费者向其他的 Broker 发起请求,这个过程会触发分区的所有权转移,即将 Broker2 拥有的分区 Topic1-Part2 的所有权转移到其他的 Broker (Broker3)。在 Apache Pulsar 中数据存储和数据服务分离,所以新 Broker 接管分区的所有权时,它不需要复制 Partiton 的数据。新的分区 Owner(Broker3)会产生一个新的分片 SegmentX+1, 如果有新数据到来,会存储在新的分片 Segment x+1 上,不会影响分区的可用性。



图五 Broker 容错

Bookie 容错

当 Bookie 节点失败时,如图六所示, 假设 Bookie 2 上的 Segment 4 损坏。Apache BookKeeper Auditor 会检测到这个错误并进行复制修复。Apache BookKeeper 中的副本修复是 Segment 级别的多对多快速修复,BookKeeper 可以从 Bookie 3 和 Bookie 4 读取 Segment 4 中的消息,并在 Bookie 1 处修复 Segment 4。如果是 Bookie 节点故障,这个 Bookie 节点上所有的 Segment 会按照上述方式复制到其他的 Bookie 节点。所有的副本修复都在后台进行,对 Broker 和应用透明,Broker 会产生新的 Segment 来处理写入请求,不会影响分区的可用性。



图六 Bookie 容错

无限制的分区存储

分片存储解决了分区容量受单节点存储空间限制的问题,当容量不够时,可以通过扩容 Bookie 节点的方式支撑更多的分区数据,也解决了分区数据倾斜问题,数据可以均匀的分配在 Bookie 节点上。Broker 和 Bookie 灵活的容错以及无缝的扩容能力让 Apache Pulsar 具备非常高的可用性。

Pulsar 特性

基于上述的设计特点,Pulsar 提供了很多特性,以下做简要的介绍。

读写分离

Pulsar 另外一个有吸引力的特性是提供了读写分离的能力,读写分离保证了在有大量滞后消费(磁盘 IO 会增加)时,不会影响服务的正常运行,尤其是不会影响到数据的写入。读写分离的能力由 Apache BookKeeper 提供,简单说一下 Bookie 存储涉及到的概念:
Journals:Journal 文件包含了 BookKeeper 事务日志,在 Ledger 更新之前,Journal 保证描述更新的事务写入到 Non-volatile 的存储介质上。
Entry logs:Entry 日志文件管理写入的 Entry,来自不同 ledger 的 entry 会被聚合然后顺序写入。
Index files:每个 Ledger 都有一个对应的索引文件,记录数据在 Entry 日志文件中的 Offset 信息。

Entry 的读写入过程如图七所示,数据的写入流程:
数据首先会写入 Journal,写入 Journal 的数据会实时落到磁盘。
然后,数据写入到 Memtable ,Memtable 是读写缓存。
写入 Memtable 之后,对写入请求进行响应。
Memtable 写满之后,会 Flush 到 Entry Logger 和 Index cache,Entry Logger 中保存了数据,Index cache 保存了数据的索引信息,然后由后台线程将 Entry Logger 和 Index cache 数据落到磁盘。

数据的读取流程:
如果是 Tailing read 请求,直接从 Memtable 中读取 Entry。
如果是 Catch-up read(滞后消费)请求,先读取 Index 信息,然后索引从 Entry Logger 文件读取 Entry。



图七 Bookie 的数据写入和读取

一般在进行 Bookie 的配置时,会将 Journal 和 Ledger 存储磁盘进行隔离,减少 Ledger 对于 Journal 写入的影响,并且推荐 Journal 使用性能较好的 SSD 磁盘,读写分离主要体现在:
写入 Entry 时,Journal 中的数据需要实时写到磁盘,Ledger 的数据不需要实时落盘,通过后台线程批量落盘,因此写入的性能主要受到 Journal 磁盘的影响。
读取 Entry 时,首先从 Memtable 读取,命中则返回;如果不命中,再从 Ledger 磁盘中读取,所以对于 Catch-up read 的场景,读取数据会影响 Ledger 磁盘的 IO,对 Journal 磁盘没有影响,也就不会影响到数据的写入。

所以数据写入是主要是受 Journal 磁盘的负载影响,不会受 Ledger 磁盘的影响。另外Segment存储的多个副本都可以提供读取服务,相比于主从副本的设计,Pulsar 可以提供更好的数据读取能力。通过以上分析,Pulsar 使用 BookKeeper 作为数据存储,可以带来下列的收益:
支持将多个 Ledger 的数据写入到同一个 Entry logger 文件,可以避免分区膨胀带来的性能下降问题。
支持读写分离,可以在滞后消费场景导致磁盘 IO 上升时,保证数据写入的不受影响。
支持全副本读取,可以充分利用存储副本的数据读取能力。

多种消费模型

Apache Pulsar 提供了多种订阅方式来消费消息,分为三种类型:独占(Exclusive),故障切换(Failover)或共享(Share)。



图八 消费模型

Exclusive 独占订阅 :在任何时间,一个消费者组(订阅)中有且只有一个消费者来消费 Topic 中的消息。

Failover 故障切换 :多个消费者(Consumer)可以附加到同一订阅。但是,一个订阅中的所有消费者,只会有一个消费者被选为该订阅的主消费者。其他消费者将被指定为故障转移消费者。当主消费者断开连接时,分区将被重新分配给其中一个故障转移消费者,而新分配的消费者将成为新的主消费者。发生这种情况时,所有未确认(ack)的消息都将传递给新的主消费者。

Share 共享订阅 :使用共享订阅,在同一个订阅背后,用户按照应用的需求挂载任意多的消费者。订阅中的所有消息以循环分发形式发送给订阅背后的多个消费者,并且一个消息仅传递给一个消费者。当消费者断开连接时,所有传递给它但是未被确认(ack)的消息将被重新分配和组织,以便发送给该订阅上剩余的剩余消费者。

多种 ACK 模型

消息确认(ACK)的目的就是保证当发生故障后,消费者能够从上一次停止的地方恢复消费,保证既不会丢失消息,也不会重复处理已经确认(ACK)的消息。在 Pulsar 中,每个订阅中都使用一个专门的数据结构 -- 游标(Cursor)来跟踪订阅中的每条消息的确认(ACK)状态。每当消费者在分区上确认消息时,游标都会更新。Pulsar 提供两种消息确认方法:
单条确认(Individual Ack),单独确认一条消息。被确认后的消息将不会被重新传递。
和累积确认(Cumulative Ack),通过累积确认,消费者只需要确认它收到的最后一条消息。

图九说明了单条确认和累积确认的差异(灰色框中的消息被确认并且不会被重新传递)。对于累计确认,M12 之前的消息被标记为 Acked。对于单独进行 ACK,仅确认消息 M7 和 M12, 在消费者失败的情况下,除了 M7 和 M12 之外,其他所有消息将被重新传送。



图九 ACK 模型

跨地域复制

Apache Pulsar 的跨地域复制机制(Geo-Replication)提供了一种全连接的异步复制,可以满足多个数据中心数据同步的使用场景。



图十 Geo-replication

如图十所示,有三个 Apache Pulsar 集群,分布于北京、上海和广州,用户创建的一个 Topic T1 设置了跨越三个数据中心做互备。在三个数据中心中,分别有三个生产者:P1、P2、P3,它们往主题 T1 中发布消息;有两个消费者:C1、C2,订阅了这个主题,接收主题中的消息。当消息由本数据中心的生产者发布成功后,会立即复制到其他两个数据中心。消息复制完成后,消费者不仅可以收到本数据中心产生的消息,也可以收到从其他数据中心复制过来的消息。

小结

Pulsar 采用了计算、存储分离的设计,并且存储在逻辑上分区,物理上分片,具有一些传统类 kafka 的 MQ 所不具备的优势,也解决了一些业界的痛点,Pulsar 目前社区比较活跃,还处于快速发展的阶段,除了以上的特性之外,Pulsar 还可以支持事务、SQL 查询、Function 等功能,另外 Pulsar 支持 protocol handler,比如 KoP(Kafka on Pulsar), 可以原生支持 Kafka 协议的数据,对于这些特性会在后续的文章中做介绍。


在最高层,一个 Pulsar 实例由一个或多个 Pulsar 集群组成。一个实例中的集群可以在它们之间复制数据。


在 Pulsar 集群中:一个或多个 Broker 处理和负载平衡来自生产者的传入消息,将消息分派给消费者,与 Pulsar 配置存储通信以处理各种协调任务,将消息存储在 BookKeeper 实例(又名 bookies)中,依赖于特定集群的 ZooKeeper 集群用于某些任务等等。由一个或多个 Bookie 组成的 BookKeeper 集群处理消息的持久存储。特定于该集群的 ZooKeeper 集群处理 Pulsar 集群之间的协调任务。Pulsar 用 Apache BookKeeper 作为持久化存储,Broker 持有 BookKeeper client,把未确认的消息发送到 BookKeeper 进行保存。

BookKeeper 是一个分布式的 WAL(Write Ahead Log)系统,Pulsar 使用 BookKeeper 有下面几个便利:
1).可以为 Topic 创建多个 Ledgers:Ledger 是一个只追加的数据结构,并且只有一个 Writer,这个 Writer 负责多个 BookKeeper 存储节点(就是 Bookies)的写入。Ledger 的条目会被复制到多个 Bookies;

2).Broker 可以创建、关闭和删除 Ledger,也可以追加内容到 Ledger;

3).Ledger 被关闭后,只能以只读状态打开,除非要明确地写数据或者是因为 Writer 挂掉导致的关闭;

4).Ledger 只能有 Writer 这一个进程写入,这样写入不会有冲突,所以写入效率很高。如果 Writer 挂了,Ledger 会启动恢复进程来确定 Ledger 最终状态和最后提交的日志,保证之后所有 Ledger 进程读取到相同的内容;

5).除了保存消息数据外,还会保存 Cursors,也就是消费端订阅消费的位置。这样所有 Cursors 消费完一个 Ledger 的消息后这个 Ledger 就可以被删除,这样可以实现 Ledgers 的定期翻滚从头写。



节点对等

从架构图可以看出,Broker 节点不保存数据,所有 Broker 节点都是对等的。如果一个 Broker 宕机了,不会丢失任何数据,只需要把它服务的 Topic 迁移到一个新的 Broker 上就行。Broker 的 Topic 拥有多个逻辑分区,同时每个分区又有多个 Segment。Writer 写数据时,首先会选择 Bookies,比如图中的 Segment1。选择了 Bookie1、Bookie2、Bookie4,然后并发地写下去。这样这 3 个节点并没有主从关系,协调完全依赖于 Writer,因此它们也是对等的。

扩展和扩容

在遇到大流量的场景时,必须增加 Consumer。这是因为 Broker 不存储任何数据,可以方便的增加 Broker。Broker 集群会有一个或多个 Broker 做消息负载均衡。当新的 Broker 加入后,流量会自动从压力大的 Broker 上迁移过来。对于 BookKeeper,如果对存储要求变高,比如之前存储 2 个副本现在需要存储 4 个副本,这时可以单独扩展 Bookies 而不用考虑 Broker。因为节点对等,之前节点的 Segment 又堆放整齐,加入新节点并不用搬移数据。Writer 会感知新的节点并优先选择使用。

容错机制

对于 Broker,因为不保存任何数据,如果节点宕机了就相当于客户端断开,重新连接其他的 Broker 就可以了。对于 BookKeeper,保存了多份副本并且这些副本都是对等的。因为没有主从关系,所以当一个节点宕机后,不用立即恢复。后台有一个线程会检查宕机节点的数据备份进行恢复。


在遇到大流量的场景时,必须增加 Consumer。

这时因为 Broker 不存储任何数据,可以方便的增加 Broker。Broker 集群会有一个或多个 Broker 做消息负载均衡。当新的 Broker 加入后,流量会自动从压力大的 Broker 上迁移过来。对于 BookKeeper,如果对存储要求变高,比如之前存储 2 个副本现在需要存储 4 个副本,这时可以单独扩展 Bookies 而不用考虑 Broker。因为节点对等,之前节点的 Segment 又堆放整齐,加入新节点并不用搬移数据。Writer 会感知新的节点并优先选择使用。


Pulsar 可以使用多租户来管理大集群。其租户可以跨集群分布,每个租户都可以有单独的认证和授权机制。租户也是存储配额、消息 TTL 和隔离策略的管理单元。


在和其他组件或者生态对接方面,Pulsar 可以支持很多种消息协议,对于存量系统的 MQ 首次接入、切换 MQ 都很方便。


Pulsar 2021 年用户报告总结

本节原文作者是 Carolyn King,原文地址,译者:sijia。

2021年7月消息,在过去的一年里 Apache Pulsar 的应用和社区活跃度发生了突飞猛进的变化。企业选择 Pulsar 的主要原因包括:容器化和云上服务成为趋势、企业生产环境的规模不断扩大、运维负担大、消息平台需要同时支持批处理和流工作负载、解锁更多使用场景等。Pulsar 是统一的消息和流平台,不仅具备云原生能力,还具备诸多其他优秀特性,如高可扩展性、高可靠性,这些独特优势可以满足许多新兴需求。这里为你详细解读 2021 年 Apache Pulsar 用户调查报告的要点信息。

目录
1.生产环境中的 Pulsar & 规模化使用 Pulsar
2.Kafka 用户选择 Pulsar
3.选择 Pulsar 的两大原因:云原生和 K8s
4.Pulsar + Flink:Pulsar 持续创新


1. 生产环境中的 Pulsar & 规模化使用 Pulsar


Pulsar 2021 年用户调查报告中最重要的两点结论为:
将 Pulsar 用于生产环境的企业数量大幅增加;
规模化使用 Pulsar 的企业数量大幅增加。


选择 Pulsar 的企业数量大幅上升,主要为在生产环境中部署 Pulsar(见上图)。Pulsar 2021 年用户调查报告显示 50% 的受访者所在团队已将 Pulsar 用于生产环境,而 2020 年这一比例仅为 31%。企业选择在生产环境中使用 Pulsar 证实了 Pulsar 具备交付关键任务的能力。

规模化使用 Pulsar
问:你所在企业每天使用 Pulsar 处理的消息量为多少?
答:12% 受访者的答案为超过 1 万亿条/天。

越来越多的企业在生产环境中使用 Pulsar,或实现企业级部署。12% 的受访者表示其所在企业使用 Pulsar 日均处理 1+ 万亿条消息,这些企业包括但不限于腾讯、Splunk、新大陆、金山云、Pactera 等。

Pulsar 在大规模使用场景中广受欢迎表明,Pulsar 在扩展性、可靠性等方面的能力足以满足当今企业的要求。值得一提的是,对于寻求消息和流一体化平台的团队而言,Pulsar 无疑是最佳选择。

2. 从 Kafka 到 Pulsar:越来越多 Kafka 用户决定使用 Pulsar

问:你所在企业除了使用 Pulsar 以外,还使用哪些消息队列?
答:68% 的受访者在使用 Pulsar 的同时,也在使用 Kafka。

问:你在用或者计划使用 Pulsar 的哪些 connector?
答:34% 的受访者选择 Kafka on Pulsar(KoP)

Kafka 用户使用 Pulsar

有多少 Kafka 用户开始使用 Pulsar?用户调查显示,在受访者中这一比例高达 68%。Kafka 更成熟、用户基数更大,不难推断,这 68% 的用户曾使用 Kafka,但现在他们决定使用 Pulsar(并非原本使用 Pulsar,而后开始使用 Kafka)。下图为 Pulsar 的活跃用户数据(来源:API7),不难看出,Apache Pulsar 社区贡献者的月活跃度已经超过 Apache Kafka 社区。2021 年 Pulsar 用户调查还显示,超过三分之一的受访者使用或计划使用 Kafka on Pulsar(KoP)。KoP 于 2020 年推出,支持用户不编写任何代码,即可将 Kafka 应用程序和服务迁移到 Pulsar。KoP 减少了 Kafka 用户使用 Pulsar 的阻碍,KoP 广受欢迎恰恰说明 Kafka 用户正在积极参与 Pulsar 的调研与使用,期待通过 Pulsar 解决 Kafka 的痛点问题,支撑更多使用场景。


Kafka 和 Pulsar 各有所长

超过三分之二(68%)的受访者正在同时使用 Kafka 和 Pulsar。Kafka 和 Pulsar 都适用于很多场景使用,这一数值似乎不合常理,但实际上 Kafka 和 Pulsar 的能力和使用场景不甚相同。Kafka 旨在支持数据管道和大规模数据迁移,而 Pulsar 更适合用于消息和数据流场景,在这些场景中,通常需要处理数量更多的 topic 和更复杂的消费模型。Pulsar 的原生特性包括多租户、跨地域复制、可扩展等,这些特性保证 Pulsar 在以下场景中表现优异,如:
(1)消息队列;
(2)发布/订阅;
(3)数据管道;
(4)流处理;
(5)微服务/事件源;
(6)数据集成;
(7)变更数据捕获;
(8)流 ETL 等。

由此可见,Pulsar 的使用范围比 Kafka 更广。在过去的 12 个月里,Pulsar 新增了大量的使用案例,例如:
1)、Splunk 多年来一直在生产环境中使用 Kafka。去年,他们决定开始引入 Pulsar。在 2020 年 Pulsar Summit 上,Karthik Ramasamy 在分享中详细解释了为什么 Splunk 决定将 Pulsar 用于 Splunk DSP(一款分析应用,日处理数据量为数十亿)。观看“为什么 Splunk 选择 Pulsar”,了解更多详细信息。

2)、Pulsar 支持处理数百万个 topic,具有高可靠性;对腾讯而言,Pulsar 的这两个特性最为重要。腾讯先后将 Pulsar 用于计费平台 Midas,联邦学习平台和腾讯游戏,取代了 Kafka 的日志管道。阅读博客原文[4],了解更多关于腾讯如何使用 Pulsar 的详细信息。

3)、Pulsar 在 Iterable 的使用历程则证明了 Pulsar 正在成为更多平台的选择。Iterable 首先使用 Pulsar 替换消息系统 RabbitMQ,然后替换 Kafka 和 Amazon SQS。阅读博文,了解更多关于 Iterable 如何使用 Pulsar 的详细信息。

用户调查报告显示,一旦企业中的某个团队开始使用 Pulsar,该企业内的其他团队也会陆续选择 Pulsar,腾讯和 Iterable 就是很好的例子。对于问题“你所在的团队是否会在 2021 年基于 Pulsar 搭建更多应用程序?”,回答“是”的受访者高达 66%,回答“在考虑中”的受访者比例为 10%。也就是说,大约 76% 的 Pulsar 用户正在考虑或计划增加 Pulsar 的使用。

3. 选择 Pulsar 的两大原因:云原生和 K8s

80% 的用户在云中使用 Pulsar;62% 的用户在 Kubernetes 上使用 Pulsar;49% 的用户认为 Pulsar 的云原生能力是他们选择 Pulsar 的最主要原因之一。

更多企业选择上云或迁移到 Kubernetes,因此需要找到可以在云上运行、高可扩展,可以充分利用 Kubernetes 并可以在其上运行良好的中间件,这一趋势促进了 Pulsar 的使用。单租户、单体架构,不支持跨地域复制和多云的系统已无法满足数据应用程序的需求。因此,越来越多的公司开始积极寻求通过云原生技术(如 Pulsar)来实现业务需求。

迁移到 Kubernetes 并非简单的迁移,这种迁移需要新的开发模式、新的工作方式,促使企业重新评估如何在云中部署和管理现有技术。例如,Kafka 等技术发布于云普及之前,因此很难映射到云和 Kubernetes 的功能。这些因素促使企业转而采用云原生技术,如 Pulsar。


4. Pulsar + Flink:Pulsar 持续创新


企业正在寻找统一的流解决方案,而 Pulsar 与 Flink 的集成增强了 Pulsar 社区的独特性,意义重大。对比 2020 年用户调查与 2021 年用户调查可知,在这一年时间里,Pulsar + Flink 用例的数量几乎翻了一番。Pulsar 的新增使用主要来自寻求实现新使用场景的公司,Pulsar + Flink 集成就是一个例子。

流处理器(如 Kafka Streams)擅长处理相对简单的流数据和近乎实时的计算,但不太适合处理大型历史数据集或需要执行多个合并操作和复杂分析的数据集。许多企业需要同时运行批数据处理器和流数据处理器,用于多条业务链,但维护多个系统既昂贵又复杂。

最近发布的新系统已经可以同时进行批处理和流处理,如 Apache Flink。目前,Flink 分别与 Kafka 和 Pulsar 结合使用进行流处理,但 Flink 的批处理功能与 Kafka 不完全兼容,因为 Kafka 只能以流交付数据,而这种方式的弊端是速度太慢,不能满足大多数批处理工作负载的要求。

Pulsar 采用分层存储模型,为 Flink 提供批处理所需的批量存储能力。借助 Pulsar + Flink,企业可以快速轻松地查询历史数据和实时数据,解锁更多竞争优势。



最新版本:2.8
Apache Pulsar 2.8.0 版本于2021年7月中旬正式发布,新版本中新增许多社区期待的性能优化与新功能。一般而言,Pulsar 每 3 个月发布一次大版本。由于 2.8.0 在开发事务 API 时投入了较多时间和精力,在 2.7.0 发布后的 6 个月,2.8.0 正式发布。新版本中的主要功能和更新如下:
独占 Producer;
包管理 API;
简化的客户端内存限制设置;
Broker Entry Metadata;
新 Protobuf 代码生成器;
事务

独占 Producer
默认情况下,Pulsar producer API 提供 “ 多 writer” 语义来将消息写入到 topic。但是,部分场景需要单个 writer 的独占访问权限,例如确保消息的非交错的线性历史或提供 leader 选举机制。这个新功能允许应用程序请求访问独占producer,以实现 “单个 writer”。它保证在任何状况下都应该只有 1 个 writer。如果 producer 失去其独占访问权,则无法在该 topic 上发布更多消息。此功能的一个用例是 Pulsar Functions 中的元数据控制器。为了编写所有 functions 元数据更新的单一线性历史(single linear history),元数据控制器需要选举一个 leader,并且这个 leader 做出的所有 “决策” 都写在元数据的 topic 上。通过利用独占 producer 功能,Pulsar 保证每个连续的 leader 上,都有元数据 topic 包含的不同的片段更新,并且不同 leader 之间没有交错。有关更多详细信息,请参阅 PIP-68: Exclusive Producer。

包管理 API
自从在 2.0 版本中引入 Pulsar Functions 以来,该功能就备受欢迎。在新版本中,我们在其优势的基础上优化了用户体验。在旧版本中,如果一个 function 被多次部署,则 function 包会被多次上传;此外,Pulsar 中没有针对 Functions 和 IO connerctor 的版本管理。新引入的包管理 API 提供更简单管理 Functions 和 IO connerctor 包的方法,并显著简化了升级和回滚过程。阅读Package Management API以获取更多详细信息。

简化的客户端内存限制设置
在 2.8.0 版本之前,producer 和 consumer 中有多个设置可以控制内部消息队列的大小。这些设置最终控制了 Pulsar 客户端使用的内存量。但是,这种方法存在个别问题使得选择控制内存总使用量的整体配置复杂。举例来说,由于这些设置基于“消息数量”,必须针对每个 producer 或 consumer 调整预期的消息大小。如果应用程序有大量(或未知)数量的 producer 或 consumer,则很难为队列大小选择合适的值。具有许多分区的 topic 也存在这样的问题。在 2.8.0 中引入了一个新的 API 来设置内存限制。此单一的 memoryLimit 设置指定给定 Pulsar 客户端上的最大内存量,producer 和 consumer 竞争分配的内存,以确保 Pulsar 客户端使用的内存不会超出设置的限制。阅读 PIP-74: Pulsar client memory limits了解详情。

Broker Entry Metadata
Pulsar 消息定义了一组非常全面的元数据属性。但是,要添加新属性,必须更改 Pulsar 协议中的 MessageMetadata 定义以通知 broker 和客户端新引入的属性。但在某些情况下,可能需要从 broker 端添加元数据属性,或者需要由 broker 以非常低的成本检索。为了防止属性在消息元数据中被反序列化,我们在 2.8.0 中引入了“Broker Entry Metadata”,以提供一种轻量级的方法来添加额外的元数据属性,而无需序列化和反序列化 protobuf 编码的 MessageMetadata。此特性为 Pulsar 解锁了一组新功能。例如,我们可以通过 broker entry metadata 为附加到 Pulsar topic 的消息生成 broker 发布时间;也可以为 Pulsar topic 的消息生成单调递增的序列 ID。我们也在 Kafka-on-Pulsar(KoP) 中使用这个特性来实现 Kafka offset。

新 Protobuf 代码生成器
Pulsar 使用 Google Protobuf 来执行客户端和 broker 之间交换的命令的序列化和反序列化。由于常规 Protobuf 部署涉及的开销,我们一直在使用 Protobuf 2.4.1 的修改版本。修改是为了确保更高效的序列化代码,该代码将线程本地缓存用于进程中的使用对象。这种方法存在一些问题。例如,Protobuf 代码生成器的补丁仅基于 Protobuf 2.4.1 版本,无法升级到更新的 Protobuf 版本。在 2.8.0 中,我们将代码生成器从修改后的 Protobuf 2.4.1 切换为 Splunk LightProto。新的代码生成器可以为 Protobuf SerDe 尽可能快地生成 Java 代码,与 proto2 定义和 Pulsar 协议 100% 兼容,并使用 Netty ByteBuf 提供零拷贝反序列化。

事务
在 Pulsar 2.8.0 之前,Pulsar 仅通过幂等 Producer 支持单个 topic 的精确一次( exactly-once)语义。虽然功能强大,但幂等 producer 只能解决 exactly-once 语义下的一小部分问题。例如,当 producer 尝试向多个 topic 生产消息时缺少 原子性。当为其中一个 topic 提供服务的 broker 崩溃时,可能会产生发布错误。如果 producer 不重试发布消息,则会导致一些消息被单次持久化并丢失其他消息;如果 producer 重试,则会导致一些消息被多次持久化。

为了解决上述问题,我们引入 Pulsar 事务 API 来支持跨多个 topic 的原子写入和确认,从而加强了 Pulsar 的交付语义。将事务 API 添加到 Apache Pulsar 完成了我们将 Pulsar 打造为一个完整的统一消息和流平台的愿景。Pulsar PMC 成员、StreamNative 工程师团队负责人李鹏辉近期在博客基于 Pulsar 事务实现 Exactly-Once 语义详细介绍了这个功能。


项目主页:
http://pulsar.apache.org/

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