在 Apache Pulsar 的底层存储系统 Apache BookKeeper 中,随着长时间运行和频繁的 Ledger 创建与删除,Bookie 节点上会产生大量的 存储碎片(Storage Fragmentation)。这些碎片不仅浪费磁盘空间,还可能影响读写性能。
为了解决这个问题,BookKeeper 提供了两个核心后台服务来实现 Ledger 碎片整理与数据健康检查:
- AutoRecovery(自动副本修复)
- Auditor(审计服务)
虽然它们的主要职责不是“传统意义上的碎片整理”,但通过 副本修复、数据一致性检查、冷数据归档 等机制,间接实现了 逻辑层面的碎片优化与存储健康管理。
📘 Pulsar 深入理解 BookKeeper:Ledger 碎片整理(AutoRecovery, Auditor)详解
一、什么是 Ledger 碎片?
1. 碎片的来源
在 BookKeeper 中,每个 Ledger 对应一个或多个物理日志文件(Entry Log),这些文件存储在 Bookie 的磁盘上。由于以下原因,会产生碎片:
来源 | 说明 |
---|---|
✅ Ledger 删除不及时 | 即使 Ledger 已被消费,其数据文件仍保留在磁盘上,直到被 GC |
✅ Entry Log 混合存储 | 多个 Ledger 的 Entry 被写入同一个 Entry Log 文件 |
✅ 部分删除 | 一个 Entry Log 中的某些 Ledger 被删除,但其他 Ledger 仍在使用,导致文件无法回收 |
✅ 未触发日志滚动 | Journal 和 Entry Log 长时间不滚动,形成大文件 |
💡 这种碎片是 逻辑碎片,不是文件系统级别的碎片,但同样影响存储效率。
二、核心组件:AutoRecovery 与 Auditor
组件 | 作用 | 是否默认启用 |
---|---|---|
Auditor | 检查 Ledger 副本完整性,发现不一致或缺失 | ✅ 默认启用 |
AutoRecovery | 自动修复缺失副本,恢复数据高可用 | ✅ 可配置启用 |
三、Auditor(审计服务)详解
1. 功能概述
- Auditor 是一个后台服务,定期扫描集群中所有 Ledger 的副本状态。
- 检查是否存在:
- 副本缺失(Under-replicated)
- 数据不一致(Inconsistent)
- 静默损坏(Silent Corruption)
2. 工作流程
Auditor 启动
↓
从 ZooKeeper 获取所有 Ledger 列表
↓
对每个 Ledger:
├─ 查询其 Ensemble(Bookie 列表)
├─ 检查每个 Bookie 是否可访问
├─ 读取 Ledger 元数据(LAC, Length)
└─ 比对副本一致性
↓
发现异常 → 写入 ZooKeeper 标记为 under-replicated
↓
触发 AutoRecovery
3. 配置参数(bookkeeper.conf
)
# 是否启用 Auditor
auditorEnabled=true
# 检查周期(默认 30 秒)
auditorPeriodicBookieCheckInterval=30
# 并发检查线程数
auditorPeriodicThreadCount=2
# 是否自动触发修复(需 AutoRecovery 开启)
auditorAutoRecoveryTrigger=true
4. 查看 Auditor 状态
# 查看 Auditor 是否运行
bookkeeper shell listjournal
# 查看 under-replicated ledgers
bookkeeper shell listunderreplicated
输出示例:
/underreplicated/ledgers/ledger-1001 /underreplicated/ledgers/ledger-1002
四、AutoRecovery(自动副本修复)详解
1. 功能概述
- AutoRecovery 是一个后台服务,监听
under-replicated
事件。 - 一旦发现某个 Ledger 副本不足,就会自动从其他副本读取数据,并写入新的 Bookie,恢复副本数。
2. 工作流程
AutoRecovery Worker 启动
↓
监听 ZooKeeper 中 /underreplicated 路径
↓
发现新 Ledger 标记
↓
选择目标 Bookie(满足 Ensemble 分布策略)
↓
从存活副本读取数据(并行)
↓
写入新 Bookie
↓
更新 Ledger 元数据(ZooKeeper)
↓
移除 under-replicated 标记
3. 配置参数(bookkeeper.conf
)
# 是否启用 AutoRecovery
autorecoveryEnabled=true
# 恢复线程数
replicationWorkerThreads=4
# 最大并发恢复任务
replicationChannelsPerWorker=5
# 修复间隔(毫秒)
auditorPeriodicBookieCheckInterval=30000
4. 手动触发 AutoRecovery
# 手动启动修复
bookkeeper shell autorecovery
# 检查修复进度
bookkeeper shell listreplicationchanges
五、如何实现“碎片整理”?
虽然 BookKeeper 没有传统意义上的“碎片整理”命令(如 defrag),但通过以下机制 间接实现存储优化:
1. Entry Log 回收(Garbage Collection)
- Bookie 后台运行 Garbage Collector(GC),定期扫描 Entry Log 文件。
- 如果某个 Entry Log 中的所有 Ledger 都已被删除,则整个文件被删除。
- 如果部分 Ledger 被删除,Bookie 会标记该文件为“可压缩”。
⚠️ 但 BookKeeper 不支持在线压缩(即 compact 文件以回收空间),必须依赖外部归档或重启清理。
2. Ledger Offload(冷数据归档)
- 将旧 Ledger 从本地磁盘迁移到云存储(如 S3、GCS)。
- 释放本地磁盘空间,减少碎片。
# 手动触发归档
pulsar-admin topics offload --size-threshold 1M my-topic
配合
managedLedgerOffloadThreshold
自动触发。
3. Journal 和 Entry Log 滚动
- Journal:Bookie 的预写日志,定期滚动(默认 2GB)。
- Entry Log:存储 Ledger 数据,也可配置滚动。
# Journal 滚动大小(默认 2GB)
journalRollingThresholdMB=2048
# Entry Log 滚动大小(默认 2GB)
logWriteCacheMaxSizeMB=2048
滚动后,旧文件可被 GC 回收,减少碎片。
六、碎片问题的监控与诊断
1. 关键监控指标
指标 | 说明 | 告警建议 |
---|---|---|
bookkeeper_client_under_replicated | 副本不足的 Ledger 数 | > 0 时告警 |
bookie_disk_usage | 磁盘使用率 | > 80% 告警 |
entry_log_count | Entry Log 文件数量 | 过多表示碎片严重 |
gc_pause_time | GC 暂停时间 | 过长影响性能 |
2. 常用诊断命令
# 查看 under-replicated ledgers
bookkeeper shell listunderreplicated
# 查看所有 Ledger
bookkeeper shell listledgers
# 检查 Ledger 完整性
bookkeeper shell ledgerchecker -l 1001
# 查看 Bookie 磁盘使用
bookkeeper shell bookieinfo
七、最佳实践:减少碎片与优化存储
实践 | 建议 |
---|---|
✅ 合理设置 Ledger 滚动策略 | 避免单个 Ledger 过大 |
✅ 启用 Ledger Offload | 将冷数据迁移到云存储 |
✅ 定期归档旧 Topic | 减少活跃 Ledger 数量 |
✅ 监控 under-replicated ledgers | 及时发现副本缺失 |
✅ 使用 SSD + 独立 Journal 磁盘 | 提升写入性能,减少 I/O 争抢 |
✅ 避免频繁创建/删除 Topic | 减少 Ledger 元数据压力 |
✅ 定期重启 Bookie(可选) | 强制 Entry Log 滚动,释放碎片空间 |
🔔 提示:真正的“碎片整理”需要结合外部归档 + 存储策略优化。
八、可视化:碎片整理流程图(文字描述)
+---------------------+
| Auditor Service |
| - 扫描所有 Ledger |
| - 发现副本缺失 |
+----------+----------+
|
v
ZooKeeper: /underreplicated
|
v
+----------+----------+
| AutoRecovery Worker |
| - 选择新 Bookie |
| - 从副本读取数据 |
| - 写入新节点 |
+----------+----------+
|
v
更新 Ledger 元数据
|
v
[副本恢复,逻辑碎片减少]
+------------+
| Ledger GC |
| - 回收空 Entry Log |
+------------+
✅ 总结
组件 | 作用 | 是否直接“碎片整理” |
---|---|---|
Auditor | 发现副本缺失与不一致 | ❌ 否(但发现问题) |
AutoRecovery | 修复副本,恢复高可用 | ✅ 间接减少碎片 |
Garbage Collector | 回收已删除 Ledger 的空间 | ✅ 是 |
Ledger Offload | 归档冷数据,释放本地空间 | ✅ 是 |
📌 一句话总结:
BookKeeper 没有传统 defrag 工具,但通过
Auditor
+AutoRecovery
+GC
+Offload
四重机制,实现了“智能碎片管理” —— 它不主动压缩文件,而是通过副本修复、数据归档和日志滚动,逐步优化存储健康。