Apache Pulsar(以下简称 Pulsar)是一个基于发布/订阅模式,且支持多租户、分布式、云原生的开源高性能消息与流平台,提供消息队列和计算服务,解决服务器间的消息传输与队列问题。
Pulsar 集合了传统消息系统(如 RabbitMQ)和基于发布 - 订阅模式的消息系统(如 Kafka)的优势,适用于服务间的实时消息传递以及大数据领域等多种应用场景。Pulsar 支持您无感知的动态扩缩容,提供更好的弹性,为您节省硬件成本。
Pulsar 采用先进的云原生架构,将有状态的存储与无状态的计算分离在不同的架构层级中,非常适合在云化的基础设施中部署、使用和运维。存算分离以及数据分散存储的架构特点,极大减少了您对计算或存储能力进行扩容时的成本与风险,特别是在扩容的时候,不需要做繁重的数据迁移,且对系统的可用性、稳定性、可运维性和运维成本优化大有裨益。
Pulsar 已在业内被广泛使用,常见的应用场景包含:高性能数据链路、微服务、即时消息、数据集成、实时数仓等。
Pulsar 具有以下重要特性:
特性 | 说明 |
---|---|
云原生 | 多层级架构,存算分离,计算和存储的横向扩展便利,同时支持云存储,便于在云上以及 Kubernetes 中部署。 |
Serverless 函数 | 通过易于使用的 API 编写 Serverless 函数,在 Pulsar 接收到数据的时候,就可以原生地处理数据,使实时数据链路更简单,不需要额外的流式数据处理引擎。 |
水平可扩展 | 可以支持大规模集群节点的无感知扩容,可以分别对计算和存储节点进行扩容,扩容操作轻量化、成本低,扩容过程中不涉及数据搬迁。支持海量 topic 的数据。 |
高稳定、低延迟 | 大规模消息生产的延迟低,稳定性高,端到端的延迟低。 |
支持跨地域副本 | 可以配置跨多个地域数据中心的数据副本。 |
多租户 | 原生的多租户系统,支持租户隔离、身份验证、用户鉴权、配额管理等。 |
持久化存储 | 基于 Apache BookKeeper 的持久化消息存储,稳定可靠,支持 IO 级别的读写操作分离。 |
客户端库 |
|
可运维性 | 提供部署、管理、工具和监控的 REST 风格 API。支持灵活多样的部署模式,如裸金属、on ECS、on Kubernetes 等方式。 |
Pulsar 支持消息队列的各种应用场景,例如:
在线场景:服务之间的异步通信、消息缓冲、系统解耦、广播通知等。
离线场景:在大数据领域,作为离线和实时数据链路的重要组成部分,承接日志上报,汇集客户端埋点日志、数据库 binlog、服务监控和日志数据等,同时也可以支持实时数仓的中间层结果数据的存储、计算与服务。
Pulsar 基于发布/订阅模式(publish-subscribe pattern,简称为 pub-sub)构建。
在这个模式中:
生产者(producers)发布(publish)消息(messages)到主题(topics);
消费者(consumers)订阅(subscribe)这些主题,处理接收到的消息,并在消息处理完成时向 Broker 发送确认(acknowledgements)。
当订阅创建后,Pulsar 会保留消息(即使消费者断开了与 Pulsar 的连接)。只有在消费者确认所有消息都成功处理之后,被保留的消息才可被丢弃。
如果消费消息失败,希望重新消费该消息,可以发送给 Broker 一个负向的确认,或者给未确认的消息开启确认超时机制,以开启消息的自动重新发送。
消息(messages)是 Pulsar 的基本处理对象“单元”,包含以下部分:
组成部分 | 描述 |
---|---|
值(Value) / 数据负载(Data payload) | 消息所承载的数据内容。消息内容是原始字节的形式,也支持对应 schema。 |
键(Key) | 消息可以通过键(可选)来打标签,在 topic 压缩等场景下会起到作用。 |
属性(Properties) | 用户自定义属性的键值对集合(可选)。 |
生产者名字(Producer name) | 生产消息的生产者的名字。如果没有指定生产者名字,则会使用默认的名字。 |
顺序 ID(Sequence ID) | 每条消息都属于其 topic 中的一个有序序列。消息的顺序 ID 是其在这个序列中的序号。 |
发布时间(Publish time) | 消息被发布时由生产者自动打上的时间戳。 |
事件时间(Event time) | 由业务应用侧在消息中附加的一个时间戳(可选)。例如,应用侧在消息被处理时附加上一个时间戳。如果没有设置事件时间,其值为 0。 |
TypedMessageBuilder | 用于构建一条消息。可以使用 |
主题(topics)与其它 Pub-Sub 系统类似,是消息从生产者到消费者传递的管道,是消息在 Pulsar 中的载体。每个主题有自己的名字,命名方式是一个结构化的 URL:
{persistent|non-persistent}://tenant/namespace/topic
具体含义如下:
组成部分 | 描述 |
---|---|
| 主题类型的标识。 |
tenant | 该主题对应的位于 Pulsar 实例中的租户(tenant)。租户是 Pulsar 多租户特性中的核心概念,可以跨 Pulsar 集群。 |
namespace | 名字空间(namespace)是主题的管理单元,用于针对相关的主题的分组机制。多数主题配置项是在名字空间层级作用的。每一个租户有一个或多个名字空间。 |
topic | 主题的名称,可以根据需要命名。 |
主题会在生产、消费时自动创建。不需要显式创建主题。
Pulsar 支持分区主题(partitioned topic)。一个分区主题可以被多个 broker 处理,从而增加了主题整体的吞吐量。分区主题的创建需要显式操作。
订阅(subscriptions)是一个被命名的配置规则,决定了消息是如何传递给消费者的。
Pulsar 支持四种订阅模式:独占的(exclusive)、故障恢复的(failover)、共享的(shared)、分键共享的(key_shared),分别介绍如下:
独占的(exclusive):只允许一个消费者关联到该订阅。是默认的订阅模式。
故障恢复的(failover):多个消费者可以关联到同一个订阅。对于每一个未分区的主题或者分区主题的每一个分区(partition),会选择一个主消费者来接收消息。当主消费者不可用时,所有未被确认的以及后续的消息将会发送给顺延的下一个消费者。
共享的(shared):多个消费者可以关联到同一个订阅。消息以各个消费者轮询调度(round robin)的方式发送给各个消费者,且任一条消息只会发送给一个消费者。当某一个消费者不可用时,所有发送给该消费者且未被确认的消息会被重新调度发送给其余的消费者。
分键共享的(key_shared):多个消费者可以关联到同一个订阅。消息会发送给不同的消费者,但是具有相同键的消息会被发送给同一个消费者。
一个 Pulsar 集群包含以下几个模块:
Broker:一个或多个 broker,完成以下工作:
处理(并负载均衡)从生产者输入的消息;
将消息输出到消费者;
和 Pulsar 的配置库(configuation store)进行通信以处理各种协同任务;
将消息存储在 BookKeeper 的节点(即 bookie)中;
基于集群对应的 ZooKeeper 完成特定的任务。
BookKeeper:一个或多个 bookie 节点,处理消息的持久化存储。
ZooKeeper:为集群处理分布式协同任务。
火山引擎 EMR 从 1.3.0 版本开始提供 On ECS 部署形态的 Pulsar 集群类型。当前集成的 Pulsar 版本为 2.9.1。详见版本概述。
Pulsar 集群类型中包含 ZooKeeper、Pulsar、BookKeeper 三个服务。
ZooKeeper 服务,包含 ZooKeeper Server 和 ZooKeeper Client 两个组件:
ZooKeeper Server 部署在 Master 节点和部分 Core 节点上(共 3 个节点),提供 Broker、Bookie 相关的元数据;
ZooKeeper Client 部署在所有节点上,提供访问 ZooKeeper 的客户端程序。
Pulsar 服务,包含 Pulsar Broker 和 Pulsar Client 两个组件。
Pulsar Broker:部署在 Master、Core、Task 节点上,负责提供读写服务以及 Pulsar 的计算逻辑;
Pulsar Client:部署在 Master、Core、Task 节点上,提供访问 Pulsar 的客户端程序。
BookKeeper 服务,包含 Bookie 组件。
Pulsar、BookKeeper 服务都依赖 ZooKeeper 服务。此外,Pulsar 服务依赖 BookKeeper 服务。
Apache Pulsar 官方网站:https://pulsar.apache.org/
Jack Vanlightly: Understanding How Apache Pulsar Works