Apache Bookkeeper

基础概念

  1. ledger: 日志流
    1. 具有全局唯一的 id
    2. 只允许追加写
    3. 提供 at-most-once 语义
  2. record: 记录,用户写入的最小单位,也叫 entry
    1. entry 归属于某个 ledger
    2. entry 具有唯一的 id
  3. bookie: 存储 ledger 的服务器

架构

  1. Metadata Store:存储 Ledger 的元数据,同时为 Client 提供服务发现功能
    • Ledger 元数据包括
      • Ledger 状态: Open / Closed
      • Ensambles: 每段 Eid 范围所在的 bookie
  2. Bookie: 存储 Ledger 的数据
    1. Journal: 日志文件,记录了追加操作,用于保证可靠性,所有 Ledger 共享同一个 journal 文件
    2. LederStorage
  3. Client: 负责处理一致性相关逻辑
    1. Writer Client 负责生成 EntryId
  4. Ensamble / Write Quorum / Ack Quorum
    1. Ensable 一组 bookie,负责存储一个 Ledger 的所有副本
    2. Write Quorum:写入分组,Write Quorum Size 即为保存副本数
    3. Ack Quorum Size:等待几个 Write Quorum 请求成功
  5. LastAddConfirmed & LastAddPushed
    1. LAP: 最后一条发送的 Eid
    2. LAC:最后一条写入成功的 Eid
      • LAC 之前的所有的 Entry 都已经 Confirm 过
      • LAP 和 LAC 之间的 Entry 是 on-flying
      • 假设发出去请求 1 和 2,2 先回来,不能把 LAC 改为 2,必须等 1 和 2 都回来了才能改成 2
      • LAC 存在 Entry Metadata 中
  6. Fencing: 防止脑裂
    • 给 bookie 发 Fenced 状态,之后我那个这个 Ledger 写的操作会失败,Client 收到 LedgerFenced 错误
    • Client 收到 LedgerFenced 错误后,会放弃 Ledger 的 Ownership
    • 新 Client 会将 LAC 之后的 Entry 进行 Forward Recovery,即尝试修复 LAC 和 LAP 之间的 Entry,这个动作由 AutoRecovery Worker 后台完成(可能同时由多个 worker 同时负责,最小粒度为 Entry)
    • 新 Client 关闭老 Ledger 并打开新 Ledger

Bookie 写入过程

  1. 先写 Journal,fsync 成功后才向 Client 返回成功,保证可靠性
    • 支持 Group Commit,在一定时间间隔内的写入的数据一次 fsync 到盘上
  2. 再写内存的 Write Cache
    • 对 Entry 按照 Lid, Eid 排序
    • Write Cache 写满之后 flush 到 Entry Log 中,并按 Ledger 生成索引
    • Entry Log 中同一个 Ledger 的 Entry 具有局部性
  3. 删除 Journal
  4. 如果 Writer 写入失败,会有新的 Writer Close 当前 Ledger 去写新的 Ledger

参考

  1. BookKeeper concepts and architecture