Apache Pulsar:核心概念、架构原理与实践
Apache Pulsar 是 Apache 顶级项目之一,凭借其“计算与存储分离”的云原生架构,集消息、存储、轻量化计算于一体,成为下一代分布式消息流平台的首选。它不仅支持多租户、跨地域复制等企业级特性,还兼容 Kafka、RabbitMQ 等生态,完美适配现代云原生应用的弹性伸缩与高可用需求。本文将结合官方课程文档,从核心概念、架构设计、关键特性到实战价值,全面拆解 Pulsar 的技术精髓。
一、Pulsar 核心定位:不止是消息队列
Apache Pulsar 是下一代云原生分布式消息流平台,并非传统意义上的消息队列。它的核心定位是“三合一”:
- 消息队列:支持 Queue/Stream 双模型,兼容 RabbitMQ、Kafka 核心能力。这意味着 Pulsar 能够满足不同业务场景下对消息队列的需求,无论是传统的队列模式还是流式处理模式,都能游刃有余。
- 数据存储:通过 BookKeeper 实现高可靠持久化,支持无限消息堆积。在数据存储方面,Pulsar 利用 BookKeeper 的分布式存储机制,确保消息的持久化和可靠性,即使在面对海量消息的情况下,也能够保证数据的完整性和持久性。
- 轻量化计算:内置 Pulsar Functions 框架,实现流数据实时处理。Pulsar 不仅提供消息传输和存储功能,还具备轻量级的计算能力,通过 Pulsar Functions 框架,用户可以快速实现对流数据的实时处理,如数据过滤、转换、聚合等操作,无需额外部署复杂的流处理引擎。
其设计初衷是解决传统消息系统的架构瓶颈(如 Kafka 计算存储耦合、RabbitMQ 扩展性不足),适配云原生环境下“弹性伸缩、多租户共享、跨地域协同”的核心需求。目前已被 Yahoo、腾讯、中国电信、VIPKID 等国内外企业广泛应用于金融、物联网、在线教育等多个行业。
二、核心概念
2.1 基础核心概念补充
2.1.1 统一消息存储模型
Pulsar 采用统一消息存储模型,同时支持 Queue 和 Stream 两种语义,核心特点如下:
无界流存储:以流的方式永久保存原始数据,无数据过期限制。这意味着数据可以长期存储,不会因为时间的推移而丢失,为数据的长期分析和挖掘提供了基础。
分区容量无上限:突破单节点存储限制,通过分片扩展存储能力。Pulsar 的分区机制允许数据在多个节点之间进行分布存储,从而突破了单个节点的存储容量限制,实现了存储能力的水平扩展。
存储灵活:可利用云存储或廉价存储(如 HDFS),降低长期存储成本。Pulsar 支持多种存储介质,用户可以根据自己的需求和成本考虑,选择合适的存储方案,如将热数据存储在高性能的存储介质中,而将冷数据存储在廉价的云存储或 HDFS 中,从而降低存储成本。
透明化存储:客户端无需关心数据存储位置,由 Pulsar 统一管理。Pulsar 对客户端隐藏了数据存储的细节,客户端只需关注消息的生产和消费,而无需关心数据存储的具体位置和方式,这大大简化了客户端的开发和使用。
2.1.2 多租户隔离机制
Pulsar 原生支持多租户,通过“Tenant(租户)→Namespace(命名空间)→Topic(主题)”三级结构实现彻底隔离:
租户(Tenant):跨集群分布,拥有独立认证授权机制和资源配额(存储/带宽限制)。租户是 Pulsar 中的最高级别隔离单位,不同租户之间在资源分配、认证授权等方面是相互独立的,从而保证了不同租户之间的隔离性。
命名空间(Namespace):租户的管理单元,同一命名空间下的 Topic 共享配置(消息 TTL、存储配额等)。命名空间是租户内部的管理单元,用于对 Topic 进行分组和管理,同一命名空间下的 Topic 可以共享一些配置信息,如消息的 TTL(生存时间)、存储配额等。
主题(Topic):消息传输最小单元,命名格式为 persistent://tenant/namespace/topic,明确归属关系。Topic 是 Pulsar 中消息传输的最小单元,通过其命名格式可以明确地表示出该 Topic 所属的租户和命名空间,从而实现了消息的层次化管理和隔离。
2.2 四种订阅模式:原理、图解与实践
2.2.1 独占模式(Exclusive):单消费者严格顺序消费
核心原理
同一 Topic 仅允许一个消费者订阅并消费,若多个消费者尝试订阅,直接抛出异常。消息按生产者发送顺序依次投递,确保全量消息的严格顺序性,是 Pulsar 的默认订阅模式。
架构图解
流程说明:
Producer1 和 Producer2 向 Topic 发送消息(顺序:message0 → message1 → message2 → message3);
Consumer A-1 独占订阅该 Topic,所有消息按发送顺序依次投递至 A-1;
若 Consumer A-0 尝试订阅同一 Topic,Broker 直接返回报错,拒绝连接;
Consumer 消费完成后发送 ACK,Broker 标记消息为已处理,后续不再重复投递。
适用场景与优缺点
-
适用场景:需要严格顺序的核心业务(如订单状态流转、金融交易日志、数据同步);
-
优点:消息顺序绝对保证,无重复消费风险,配置简单;
-
缺点:单消费者存在性能瓶颈,消费者故障会导致消费停滞(需手动重启或切换)。
2.2.2 灾备模式(Failover):多消费者故障自动切换
核心原理
同一 Topic 可注册多个消费者,Broker 按消费者连接顺序排序,仅让“活跃消费者”处理消息,其他消费者作为备用。当活跃消费者故障(如网络断开、进程崩溃),Broker 自动将备用消费者升级为活跃状态,继续消费,保证服务连续性。
架构图解
流程说明:
Producer1 和 Producer2 向 Topic 发送消息,初始状态下 Consumer B-2 为活跃消费者,接收所有消息;
当 Consumer B-2 故障(如服务器宕机),Broker 检测到连接断开后,自动将排序第二的 Consumer B-1 升级为活跃消费者;
Consumer B-1 从 B-2 未消费完成的消息(如 message3、message4)开始继续处理,无消息丢失;
支持动态添加备用消费者,提升高可用等级。
适用场景与优缺点
-
适用场景:高可用核心业务(如支付通知、风控告警、实时消息推送);
-
优点:故障自动切换,无人工干预,保证消息顺序,服务可用性高;
-
缺点:同一时间仅一个消费者工作,吞吐量受限于单个消费者性能。
2.2.3 共享模式(Shared):多消费者轮询并行消费
核心原理
同一 Topic 可注册多个消费者,Broker 采用 Round-Robin 轮询机制分发消息,每条消息仅投递至一个消费者。支持动态增减消费者节点,吞吐量随消费者数量线性提升,但不保证消息顺序。
架构图解
流程说明:
Producer1 和 Producer2 向 Topic 发送消息(message0 → message1 → message2 → message3 → message4);
Broker 通过轮询机制分发消息:message0 投递给 Consumer C-1,message1 投递给 C-2,message2 投递给 C-3,message3 再次投递给 C-1;
若 Consumer C-2 断开连接,其未消费的消息(如 message4)会重新分配给其他存活的消费者(C-1 或 C-3);
消费者独立处理消息并发送 ACK,互不影响,支持高并发处理。
适用场景与优缺点
-
适用场景:高吞吐无序场景(如日志采集、监控数据上报、任务分发);
-
优点:支持水平扩展,吞吐量高,消费者故障不影响整体服务;
-
缺点:不保证消息顺序,不支持累积确认(仅支持单条确认),可能存在重复消费(如消费者故障后消息重投)。
2.2.4 键共享模式(Key_Shared):同 Key 顺序+多消费者并行
核心原理
消息与消费者均绑定 Key,Broker 按消息 Key 的哈希值定向分发,同一 Key 的消息始终投递至同一个消费者,保证同 Key 消息的顺序性;不同 Key 的消息可分发至不同消费者,实现并行处理,兼顾顺序与吞吐量。
架构图解
流程说明:
Producer1 和 Producer2 发送带 Key 的消息:<k1.v1>、<k1.v2>(Key=k1),<k2.v3>(Key=k2),<k3.v1>、<k3.v2>(Key=k3);
Broker 按 Key 哈希分发:k1 消息投递给 Consumer D-1,k2 消息投递给 D-2,k3 消息投递给 D-3;
同 Key 消息按发送顺序处理(如 <k1.v1> 先于 <k1.v2> 投递),不同 Key 消息并行处理;
新增消费者时,Broker 会重新分配部分 Key 的消息,确保负载均衡;消费者故障后,其负责的 Key 会迁移至其他消费者。
适用场景与优缺点
-
适用场景:按分组顺序消费的高吞吐场景(如用户行为分析、会话跟踪、订单履约);
-
优点:兼顾同 Key 顺序与整体吞吐量,支持动态扩缩容,负载均衡;
-
缺点:配置稍复杂(需启用 KEY_BASED 批处理),Key 分布不均可能导致部分消费者负载过高。
2.2.5 四种订阅模式对比总结
| 模式 | 消息顺序性 | 消费者数量限制 | 吞吐量 | 高可用性 | 核心适用场景 |
|---|---|---|---|---|---|
| Exclusive | 全量严格顺序 | 1个 | 低 | 低(需手动恢复) | 订单状态流转、金融交易日志 |
| Failover | 全量严格顺序 | 多个(仅1个活跃) | 中 | 高(自动切换) | 支付通知、风控告警 |
| Shared | 无顺序 | 多个 | 高 | 高(故障自动重分配) | 日志采集、监控数据上报 |
| Key_Shared | 同 Key 严格顺序 | 多个 | 高 | 高(Key 迁移) | 用户行为分析、会话跟踪 |
三、云原生架构设计:计算与存储分离的精髓
Pulsar 最核心的架构创新是计算与存储分离,彻底解决了传统消息系统“扩容难、故障影响大”的痛点。
3.1 架构组成三大部分
(引用自 Apache Pulsar 官网)
Broker 集群:无状态计算节点
-
核心职责:消息路由、负载均衡、分发消费、跨集群复制。Broker 负责接收生产者发送的消息,并将消息路由到相应的存储节点(BookKeeper),同时负责将消息分发给消费者,并处理跨集群的消息复制工作。
-
关键特性:无状态设计,扩容/缩容/替换不影响数据,支持 K8s 弹性调度。由于 Broker 是无状态的,因此在进行扩容、缩容或替换操作时,不会对数据产生影响,这使得 Broker 非常适合在 Kubernetes 等容器编排平台上进行弹性调度。
-
内部组件:HTTP 服务器(管理接口)、TCP 调度器(数据传输)。Broker 内部包含 HTTP 服务器,用于提供管理接口,方便用户对集群进行管理和监控;同时,它还包含 TCP 调度器,用于处理数据的传输工作。
BookKeeper 集群:持久化存储节点(Bookie)
- 核心职责:消息持久化存储,支持多副本容错。BookKeeper 负责将消息持久化存储到磁盘上,并通过多副本机制来保证数据的可靠性,即使部分存储节点出现故障,也不会导致数据丢失。
- 关键特性:
- 分片存储:消息按 Ledger→Segment→Entry 分层存储,独立扩容无瓶颈。BookKeeper 采用分片存储机制,将消息存储在多个 Ledger 中,每个 Ledger 又分为多个 Segment,每个 Segment 包含多个 Entry,这种分层存储结构使得存储容量可以独立进行扩容,不存在瓶颈问题。
- IO 隔离:日志与数据分盘存储,读写互不干扰,提升并发性能。BookKeeper 将日志和数据分别存储在不同的磁盘上,从而实现了读写操作的隔离,避免了读写操作之间的相互干扰,提高了并发性能。
- 高并发:单 Bookie 支持数千 Ledger 并发读写,适配高吞吐场景。每个 Bookie 节点都能够支持数千个 Ledger 的并发读写操作,这使得 BookKeeper 能够很好地适配高吞吐量的场景。
3.2 核心数据流转流程
-
生产者发送消息到 Broker,支持同步/异步发送,批量发送时可累积消息提升效率。生产者可以通过同步或异步的方式将消息发送到 Broker,为了提高发送效率,还可以采用批量发送的方式,将多条消息累积在一起后一起发送。
-
Broker 将消息写入本地缓存以降低延迟,同时异步同步到 BookKeeper 集群(多副本存储确保可靠性)。Broker 接收到消息后,会先将消息写入本地缓存,以降低消息发送的延迟,然后异步地将消息同步到 BookKeeper 集群中,并采用多副本存储的方式,确保消息的可靠性。
-
BookKeeper 以 Ledger 为单位存储消息,每个 Ledger 包含多个 Segment,实现数据分片管理。BookKeeper 接收到消息后,会以 Ledger 为单位将消息存储起来,每个 Ledger 包含多个 Segment,通过这种方式实现数据的分片管理,提高了存储的灵活性和扩展性。
-
消费者通过订阅从 Broker 拉取消息,支持同步接收或异步回调。消费者可以通过订阅的方式从 Broker 拉取消息,支持同步接收或异步回调的方式,根据具体的应用场景选择合适的接收方式。
-
消费者消费完成后发送 ACK 确认,Broker 收到 ACK 后标记消息状态,按需清理或保留(遵循 Namespace 级别的保留策略)。消费者在消费完消息后,会发送 ACK 确认消息给 Broker,Broker 收到 ACK 后会标记消息的状态,然后根据 Namespace 级别的保留策略,决定是否清理或保留该消息。
3.3 架构优势对比传统 MQ
| 对比维度 | 传统 MQ(Kafka/RocketMQ) | Pulsar 架构 |
|---|---|---|
| 架构模式 | 计算存储耦合 | 计算存储分离 |
| 扩容能力 | 整体扩容,成本高 | 独立扩容(Broker/Bookie) |
| 故障影响 | 存储节点故障影响计算 | 故障隔离,影响范围小 |
| 存储灵活性 | 本地磁盘,扩容受限 | 分层存储,支持云存储 |
| 多租户支持 | 弱支持(需二次开发) | 原生支持,隔离性强 |
| 消费模型适配 | 单一模型(流/队列二选一) | 统一模型,同时支持流+队列 |
3.4 与 Kafka 核心差异补充
| 对比维度 | Kafka | Pulsar |
|---|---|---|
| 存储模型 | 基于 Partition 分区+副本存储 | 基于 Ledger→Segment→Entry 分层存储 |
| 消费模型 | 消费者组模式,1 分区对应 1 消费者 | 订阅+Cursor 模式,多订阅独立消费 |
| 部署复杂度 | 去除 ZK 后部署简单 | 依赖 ZK+BookKeeper,部署较复杂 |
| 多租户支持 | 无原生支持 | 原生 Tenant+Namespace 三级隔离 |
| 吞吐量(2c4g) | 20 万级 QPS | 100 万级 QPS |