Apache Pulsar 深度源码级架构解析

Apache Pulsar 深度源码级架构解析

—— 千亿级消息引擎的底层实现艺术


一、分层存储架构:Segment 分片与冷热分离

设计思想

基于 LSM-Tree 变体 + 分片策略,实现数据生命周期管理:

Hot Data (BookKeeper) → Warm Data (SSD Cache) → Cold Data (Object Storage)
源码实现(行级剖析)

关键类org.apache.pulsar.broker.service.persistent.PersistentTopic

// 创建 Segment 分片 (行号: 842)
public void createNewSegmentIfNeeded() {
   
    if (currentSegment.isFull()) {
    // 当前 Segment 达到阈值
        LedgerHandle newLedger = bookkeeper.createLedger(
            ensembleSize, writeQuorumSize, ackQuorumSize, // 副本策略
            DigestType.CRC32, passphrase);
        currentSegment.close();  // 关闭旧 Segment (只读)
        currentSegment = new Segment(newLedger); // 激活新 Segment
        offloadOldSegments();    // 触发冷数据下沉 (行号 901)
    }
}

冷数据下沉流程

graph TB
A[Segment Full] --> B{是否达到冷数据阈值?}
B -->|Yes| C[标记 Segment 为只读]
C --> D[启动 Offloader 线程]
D --> E[上传数据到 S3/HDFS]
E --> F[更新 ZK 元数据]
F --> G[删除本地副本]
参数调优
参数 默认值 优化建议
managedLedgerMaxSizePerSegment 128MB 根据消息大小调整(小消息设小值)
offloadThresholdInBytes -1 (禁用) 设为热存储容量的 80%
高深扩展:冷热分离一致性协议

采用 Versioned CAS(Compare-and-Swap) 保证数据一致性:

// OffloaderScheduler.java (行号 215)
long expectedVersion = zkStore.getDataVersion();
if (zkStore.compareAndSetOffloadPosition(segmentId, expectedVersion, newVersion)) {
   
    uploadSegment(segment); // 原子性提交
}

速记口诀
“分片大小阈值控,副本策略三参数;
冷热下沉原子锁,ZK 版本保一致”

源码路径
PersistentTopic.java
参考文献
VLDB’17: BookKeeper’s Segment-based Storage


二、写入流程:多级流水线优化

核心设计

三阶段管道化处理

  1. Producer 批处理:内存合并小消息
  2. Broker 转发:异步并行写 Bookies
  3. Bookie 持久化:Journal + Ledger 双写
源码级流水线剖析
// ProducerImpl.java (行号 687)
public void sendAsync(Message message) {
   
    batcher.add(message); // 1. 批量聚合 (行号 705)
}

// PersistentTopic.java (行号 1124)
void publishMessage(ByteBuf data) {
   
    managedLedger.asyncAddEntry(data, new AddEntryCallback() {
   
        public void addComplete() {
   
            // 2. 并行写 Bookies (行号 1188)
            for (Bookie bookie : ensemble) {
   
                bookie.asyncAddEntry(ledgerId, entryData);
            }
        }
    });
}

// Bookie.java (行号 1523)
void asyncAddEntry(long ledgerId, byte[] data) {
   
    journal.write(data); // 3.1 写 Journal (同步刷盘)
    entryLogger.addEntry(ledgerId, data); // 3.2 写 Ledger (异步刷盘)
}
IO 隔离机制
Bookie Internal
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北漂老男人

防秃基金【靠你的打赏续命】

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值