Pulsar BookKeeper存储层的Segment读写机制
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,冷数据在对象存储