自 LinkedIn 2011 年建立了 Apache Kafka 后,这款消息系统一度成为大规模消息系统的惟一选择。为何呢?由于这些消息系统天天须要传递数百万条消息,消息规模确实很庞大(2018 年 Twitter 推文平均天天 500 万条,用户数平均天天为 1 亿)。那时,咱们没有 MOM 系统来处理基于大量订阅的流数据能力。因此,不少大牌公司,像 LinkedIn、Yahoo、Twitter、Netflix 和 Uber,只能选择 Kafka。javascript
现在到了 2019 年,世界发生了巨变,天天的消息增量高达数十亿,支持平台也须要相应扩展,以知足持续增加的须要。所以,消息系统须要在不影响客户的状况下持续地无缝扩展。Kafka 在扩展方面存在诸多问题,系统也难以管理。Kafka 的粉丝对此说法可能很有微词,然而这并不是我的偏见,我自己也是 Kafka 的粉丝。客观的说,随着世界的发展和创新,新工具比旧工具更加方便易用,咱们天然会感受原来的工具漏洞百出,很难使用。天然发展,一直如此。html
这时,一款新的产品应运而生——它就是“Apache Pulsar”!java
2013 年雅虎建立了 Pulsar,并于 2016 年把 Pulsar 捐给了 Apache 基金会。Pulsar 现已成为 Apache 的顶级项目,得到举世瞩目的承认。雅虎和 Twitter 都在使用 Pulsar,雅虎天天发送 1000 亿条消息,两百多万个主题。这样的消息量,听起来很难以想象吧,但确实是真的!apache
接下来咱们了解下 Kafka 痛点以及 Pulsar 对应的解决方案。api
Kafka 很难进行扩展,由于 Kafka 把消息持久化在 broker 中,迁移主题分区时,须要把分区的数据彻底复制到其余 broker 中,这个操做很是耗时。安全
当须要经过更改分区大小以得到更多的存储空间时,会与消息索引产生冲突,打乱消息顺序。所以,若是用户须要保证消息的顺序,Kafka 就变得很是棘手了。服务器
若是分区副本不处于 ISR(同步)状态,那么 leader 选取可能会紊乱。通常地,当原始主分区出现故障时,应该有一个 ISR 副本被征用,可是这点并不能彻底保证。若在设置中并未规定只有 ISR 副本可被选为 leader 时,选出一个处于非同步状态的副本作 leader,这比没有 broker 服务该 partition 的状况更糟糕。架构
使用 Kafka 时,你须要根据现有的状况并充分考虑将来的增量计划,规划 broker、主题、分区和副本的数量,才能避免 Kafka 扩展致使的问题。这是理想情况,实际状况很难规划,不可避免会出现扩展需求。异步
Kafka 集群的分区再均衡会影响相关生产者和消费者的性能。分布式
发生故障时,Kafka 主题没法保证消息的完整性(特别是遇到第 3 点中的状况,须要扩展时极有可能丢失消息)。
使用 Kafka 须要和 offset 打交道,这点让人很头痛,由于 broker 并不维护 consumer 的消费状态。
若是使用率很高,则必须尽快删除旧消息,不然就会出现磁盘空间不够用的问题。
众所周知,Kafka 原生的跨地域复制机制(MirrorMaker)有问题,即便只在两个数据中心也没法正常使用跨地域复制。所以,甚至 Uber 都不得不建立另外一套解决方案来解决这个问题,并将其称为 uReplicator 。
要想进行实时数据分析,就不得不选用第三方工具,如 Apache Storm、Apache Heron 或 Apache Spark。同时,你须要确保这些第三方工具足以支撑传入的流量。
Kafka 没有原生的多租户功能来实现租户的彻底隔离,它是经过使用主题受权等安全功能来完成的。
固然,在生产环境中,架构师和工程师有办法解决上述问题;可是在平台/解决方案或站点可靠性上,这是个让人头疼的问题,这并不像在代码中修复逻辑,而后将打包的二进制文件部署到生产环境中那么简单。
如今,咱们来聊聊 Pulsar,这个竞争领域中的领跑者。
Apache Pulsar 是一个开源分布式发布-订阅消息系统,最初由雅虎建立。若是你了解 Kafka,能够认为 Pulsar 在本质上和 Kafka 相似。
Pulsar 表现最出色的就是性能,Pulsar 的速度比 Kafka 快得多,美国德克萨斯州一家名为 GigaOm 的技术研究和分析公司对 Kafka 和 Pulsar 的性能作了比较,并证明了这一点。
与 Kafka 相比,Pulsar 的速度提高了 2.5 倍,延迟下降了 40%。(来源在这里)。
请注意,该性能比较是针对 1 个分区的 1 个主题,其中包含 100 字节消息。而 Pulsar 每秒可发送 220,000+ 条消息,以下所示。
这点 Pulsar 作的确实很棒!
就冲这一点,放弃 Kafka 而转向 Pulsar 绝对很值,接下来,我会详细剖析 Pulsar 的优点和特色。
Pulsar 既支持做为消息队列以 Pub-Sub 模式使用,又支持按序访问(相似 Kafka 基于 Offset 的阅读),这给用户提供了极大的灵活性。
针对数据持久化,Pulsar 的系统架构和 Kafka 不一样。Kafka 在本地 broker 中使用日志文件,而 Pulsar 把全部主题数据存储在 Apache BookKeeper 的专用数据层中。简单地说,BookKeeper 是一种高可扩展、强容灾和低延时的存储服务,而且针对实时持久的数据工做负载进行了优化。所以,BookKeeper 保证了数据的可用性。而 Kafka 日志文件驻留在各个 broker 以及灾难性服务器故障中,因此 Kafka 日志文件可能出现问题,不能彻底确保数据的可用性。这个有保证的持久层(guaranteed persistence layer)给 Pulsar 带来了另外一个优点,即“broker 是无状态的”。这与 Kafka 有本质的区别。Pulsar 的优点在于 broker 能够无缝地水平扩展以知足不断增加的需求,由于它在扩展时不须要移动实际数据。
若是一个 Pulsar broker 宕机了怎么办?主题会被当即从新分配给另外一个 broker。因为 broker 的磁盘中没有主题数据,服务发现会自行处理 producer 和 consumer。
Kafka 须要清除旧数据才能使用磁盘空间;与 Kafka 不一样,Pulsar 把主题数据存储在一个分层结构中,该结构能够链接其余磁盘或 Amazon S3,这样就能够无限扩展和卸载主题数据的存储量。更酷的是,Pulsar 向消费者无缝地显示数据,就好像这些数据在同一个驱动器上。因为不须要清除旧数据,你能够把这些组织好的 Pulsar 主题用做“数据湖(Data Lake)”,这个用户场景仍是颇有价值的。固然,须要的时候,你也能够经过设置,清除 Pulsar 中的旧数据。
Pulsar 原生支持在主题命名空间级别使用数据隔离的多租户;而 Kafka 没法实现这种隔离。此外,Pulsar 还支持细粒度访问控制功能,这让 Pulsar 的应用程序更加安全、可靠。
Pulsar 有多个客户端库,可用于 Java、Go、Python、C++ 和 WebSocket 语言。
Pulsar 原生支持功能即服务(FaaS),这个功能很酷,就和 Amazon Lambda 同样,能够实时分析、聚合或汇总实时数据流。使用 Kafka,还须要配套使用像 Apache Storm 这样的流处理系统,这会额外增长成本,维护起来也很麻烦。在这点上,Pulsar 就远远赛过 Kafka。截至目前,Pulsar Functions 支持 Java、 Python 和 Go 语言,其余语言将在之后的版本中陆续获得支持。
Pulsar Functions 的用户案例包括基于内容的路由(content based routing)、聚合、消息格式化、消息清洗等。
以下是字数计算示例。
package org.example.functions;import org.apache.pulsar.functions.api.Context;import org.apache.pulsar.functions.api.Function;import java.util.Arrays;public class WordCountFunction implements Function<String, Void> { // This is invoked every time messages published to the topic @Override public Void process(String input, Context context) throws Exception { Arrays.asList(input.split(" ")).forEach(word -> { String counterKey = word.toLowerCase(); context.incrCounter(counterKey, 1); }); return null; }}
Pulsar 支持多个数据接收器(data sink),用于为主要产品(如 Pulsar 主题自己、Cassandra、Kafka、AWS Kinesis、弹性搜索、Redis、Mongo DB、Influx DB 等)路由处理过的消息。
此外,还能够把处理过的消息流持久化到磁盘文件。
Pulsar 使用 Pulsar SQL 查询历史消息,使用 Presto 引擎高效查询 BookKeeper 中的数据。Presto 是用于大数据解决方案的高性能分布式 SQL 查询引擎,能够在单个查询中查询多个数据源的数据。以下是使用 Pulsar SQL 查询的示例。
show tables in pulsar."public/default"
Pulsar 内置强大的跨地域复制机制,可在不一样区域的不一样集群之间即时同步消息,以维护消息的完整性。在 Pulsar 主题上生成消息时,消息首先保留在本地集群中,而后异步转发到远程集群。在 Pulsar 中,启用跨地域复制是基于租户的。只有建立的租户能够同时访问两个集群时,这两个集群之间才能启用跨地域复制。
对于消息传递通道安全,Pulsar 原生支持基于 TLS 和基于 JWT token 的受权机制。所以,你能够指定谁能够发布或使用哪些主题的消息。此外,为了提升安全性,Pulsar Encryption 容许应用程序在生产者端加密全部消息,并在 Pulsar 传递加密消息到消费者端时解密。Pulsar 使用应用程序配置的公钥/私钥对执行加密。具备有效密钥的消费者才能解密加密消息。但这会带来性能损失,由于每条消息都须要加密和解密才能进行处理。
目前在使用 Kafka 而且但愿迁移到 Pulsar 的用户大可放心,Pulsar 原生支持经过链接器(connector)直接使用 Kafka 数据,或者你能够把现有的 Kafka 应用程序数据导入到 Pulsar,这个过程也至关容易。
这篇文章并非说大规模消息处理平台不能使用 Kafka,只能选择 Pulsar。我要强调的是,Kafka 的痛点 Pulsar 已经有了很好的解决方案,这对任何工程师或架构师来讲都是一件好事。另外,在体系架构方面 Pulsar 在大型消息传递解决方案中的速度要快得多,随着雅虎和 Twitter(以及许多其余公司)把 Pulsar 部署到生产环境,说明 Pulsar 稳定性足以支撑任何生产环境。虽然从 Kafka 转到 Pulsar,会经历一个小小的学习曲线,但相应的投资回报率仍是很客观的!
— THE END —