Apache Pulsar 自诞生并从 Apache 软件基金会毕业以来,已发展为完整的项目并形成了全球上万人的社区。今年,值此 Pulsar 北美峰会收官和 Pulsar 2.8.0 版本发布之际,Pulsar 在项目和社区上都迎来了新的里程碑。借此机会,我们共同回顾 Pulsar 的技术及生态发展。
Apache Pulsar 在全球有数百家公司广泛采用,包括 Splunk、腾讯、Verizon 和 Yahoo! JAPAN 等。Apache Pulsar 从一开始的只是一款云原生分布式消息系统,现已发展成为一个完整的消息和流的平台,可用于发布和订阅、实时存储和处理大规模数据流。
Pulsar 诞生于 2012 年,最初的目的是为在 Yahoo 内部,整合其他消息系统,构建统一逻辑、支撑大集群和跨区域的消息平台。当时的其他消息系统(包括 Kafka),都不能满足 Yahoo 的需求,比如大集群多租户、稳定可靠的 IO 服务质量、百万级 Topic、跨地域复制等,因此 Pulsar 应运而生。
当时,通常有两种类型的系统来处理动态数据:实时处理关键业务事件的消息队列,以及大规模处理可扩展数据管道的流系统。许多公司不得不将他们的功能限制在其中一种,或者不得不采用多种不同的技术。如果选择多种技术通常会导致数据隔离和数据孤岛:一个用于消息队列的孤岛来构建应用服务,另一个用于构建数据服务的流系统。公司的基础设施通常极其复杂,下图说明该架构。
然而,随着公司需要处理的数据类型增多,运营数据(如日志数据、点击事件等),以及需要访问组合业务数据和运营数据的下游系统数量的增加,系统需要支持消息队列和流两种场景。
除此之外,公司需要一个基础设施平台,允许他们在其上构建所有应用程序,然后让这些应用程序默认处理动态数据(消息和流数据)。通过这种方式,可以显著简化实时数据基础设施,如下图。
在这样的愿景下,Yahoo! 团队开始致力于为动态数据构建统一的消息流平台。以下是 Pulsar 成立至今的关键里程碑。
Pulsar 的诞生始于 Apache BookKeeper。Apache BookKeeper 为连续流实现了类似日志的抽象,并提供了在互联网规模上使用简单的写-读日志 API 运行它的能力。日志为构建分布式系统提供了很好的抽象,如分布式数据库和发布-订阅消息。写入 API 以附加到日志的形式出现。读取 API 是从 reader 定义的起始偏移量连续读取。BookKeeper 的实现奠定了基础——可扩展的基于日志的消息和流系统。
在可扩展的日志存储之上引入了一个无状态服务层,通过运行无状态 broker 来发布和消费消息。这种多层架构将服务/计算与存储分离,允许 Pulsar 在不同的层中管理服务和存储。
这种架构保证了即时可扩展性和更高的可用性,使 Pulsar 非常适合构建关键任务服务,例如金融场景中的计费平台、电子商务和零售商的交易处理系统以及金融机构的实时风险控制系统。
在现代数据架构中,实时场景通常可以分为两类:队列和流。队列通常用于构建核心业务应用程序服务,流通常用于构建实时数据服务,如数据管道。
为了提供一个能够同时为应用程序和数据服务提供服务的平台,需要一个集成了队列和流语义的统一消息模型。Pulsar topic 成为消费的真正来源。消息只能在 topic 上存储一次,但可以通过不同的订阅以不同的方式消费。这种统一大大降低了管理和开发消息和流应用程序的复杂性。
接着,Pulsar 内添加了新的 Pulsar schema registry 和一个新安全类型 producer 和 consumer API。内置的 schema registry 使 Pulsar topic 上的消息 producer 和 consumer 能够通过 Pulsar broker 本身协调 topic 数据的结构,而无需外部协调机制。使用 schema 数据,通过 Pulsar 传输的每条数据都是完全可发现的,用户能够构建轻松适应数据变化的系统。
此外,schema registry 会跟踪 schema 版本之间的数据兼容性。随着新的 schema 的上传,registry 保证旧的 consumer 能够读取新的 schema 版本,以确保 producer 不能破坏 consumer。
下一步是构建 API,以便轻松地从 Pulsar 输入输出并处理数据。其目标是使用 Apache Pulsar 轻松构建事件驱动的应用程序和实时数据管道,无论来自何处,用户都可以在事件到达时对其进行处理。
Pulsar IO API 使用户可以通过插入各种 source connector - 将数据从外部系统输入到 Pulsar 、sink connector - 将数据从 Pulsar 输出到外部系统,来构建实时流数据管道。目前,Pulsar 提供了多个内置 connector,用户开箱即用。
此外,StreamNative 维护的 StreamNative Hub[1](Pulsar connector 的 registry),提供了数十个与流行数据系统集成的 connector。如果 IO API 用于构建流数据管道,则 Functions API 用于构建事件驱动的应用程序和实时流处理器。
无服务器 function 的概念被用于流处理,然后将 Functions API 构建为轻量级无服务器库,用户可以使用任何语言编写任何事件、处理逻辑。工程师团队无需运行和维护另一个集群就能够编写流处理逻辑。
随着 Apache Pulsar 的普及以及 Pulsar 中存储的数据量的增加,用户最终遇到了“保留悬崖”(retention cliff),此时在 Apache BookKeeper 中存储、管理和检索数据的成本变得更加昂贵。为了解决这个问题,运维工程师和应用程序开发人员通常使用 AWS S3 等外部存储作为长期存储的 sink,然而这样会失去 Pulsar 的不可变流和排序语义的大部分优势,而用户最终不得不管理具有不同访问模式的两套系统。
分层存储的引入支持 Pulsar 将大部分数据卸载到远程云原生存储。这种更便宜的存储形式很容易随着数据量而扩展。更重要的是,通过分层存储,Pulsar 提供了在与 Flink 等批流融合处理器集成时所需的批处理存储能力。与 Pulsar 集成的批流一体使公司能够快速轻松地查询具有历史背景的实时流,增加竞争优势。
在引入分层存储之后,Pulsar 从一个 Pub/Sub 消息系统演变为一个可扩展的流数据系统,可以接收、存储和处理数据流。但是,使用其他消息协议(例如 Kafka、AMQP、MQTT 等)编写的现有应用程序必须重写才能采用 Pulsar 的消息协议。
插件协议 API 进一步降低了采用 Pulsar 构建消息流的开销,开发人员可利用 Pulsar 架构提供的所有优势将 Pulsar 功能扩展到其他消息领域。于是 StreamNative 和其他行业领导者展开合作,开发流行的插件协议,包括:
最近,事务被添加到 Apache Pulsar,以便为流处理启用 exactly-once 语义。这项基本功能为流数据转换提供了强有力的保证,可以轻松构建可扩展、容错、有状态的消息流应用程序来处理流数据。
此外,事务 API 功能不限于已有的客户端语言。Pulsar 对事务性消息流的支持是一种可以用任何语言呈现的协议级功能。此类协议级功能可用于各种应用程序。
除了对 Pulsar 技术持续升级,社区还致力于建立一个强大的周边生态系统。Pulsar 能够支持丰富的 pub-sub 库、connector、function、插件协议以及与流行引擎集成的生态系统,使 Pulsar 用户能够简化工作流程并应用于新的场景。
欢迎关注 Twitter @apache_pulsar 或 @streamnativeio。