CodeWalk

Pulsar BookKeeper存储层的Segment读写机制

作者:Yahuda · 2026-05-30 12:55

Pulsar依赖Apache BookKeeper作为底层存储引擎,请解释BookKeeper的Segment(Ledger)存储模型:写入流程(Ensemble/Write Quorum/Ack Quorum)、读取流程(Fencing/Recovery)、以及End-to-End延迟控制机制。为什么BookKeeper能支持百万级Topic而不会出现Kafka的『分区数瓶颈』?

回答

Yahuda

Pulsar BookKeeper存储层详解:

1. Ledger(Segment)存储模型

  • Pulsar将消息写入多个Ledger(Segment),每个Ledger大小可配置
  • Ledger分布在多个BookKeeper节点上
  • 一个Topic由一系列Ledger组成

2. 写入三参数

Ensemble (E) = 3    # 数据分布的Bookie节点数
Write Quorum (Qw) = 3  # 每次写入需确认的副本数
Ack Quorum (Qa) = 2   # 返回ACK的最少副本数
  • 写入流程:消息写入E个Bookie,至少Qa个成功才返回
  • E=3,Qw=3,Qa=2:保证2副本确认即成功,容忍1个Bookie故障

3. 读取流程

  • 读取时找Ledger中任意存活且有数据的Bookie
  • 故障恢复:通过Fencing机制(Ledger关闭后不可再写)
  • 自动从其他副本读取

4. 为什么Pulsar支持百万级Topic: | 问题 | Kafka(Broker存数据) | Pulsar(BookKeeper存数据) | |------|---------------------|---------------------------| | 分区数瓶颈 | Broker需管理元数据和数据索引,分区>10000时性能下降 | Broker只做计算和路由,数据存BK,无分区数硬上限 | | 存储压力 | 每个分区独立文件句柄 | BookKeeper统一管理,Segment粒度 | | Rebalance | 需移动数据 | 仅元数据变更,无数据移动 |

5. 延迟控制

  • Pipeline写入:多条消息流水线式发送,避免串行等待
  • 预分配Ledger:提前生成Ledger避免创建延迟
  • 读修复:并行读取,选择响应最快的副本

6. 分层存储

  • 旧Ledger自动Offload到S3/HDFS(NFS/S3 Offloader)
  • 热数据在BookKeeper,冷数据在对象存储