Doris 实战与架构

分析型数据库 / 源码阅读 / LESSON 12

BE 副本一致性与修复

理解 BE 副本一致性、Clone、Repair 与 Tablet 健康治理的协作方式。

阅读时间
30 分钟 | **前置阅读**: [doc-00](doc-00-architecture-overview.md) §2, [doc-06](doc-06-storage-tablet-rowset-segment.md) (Tablet)
学习路径
Doris 实战与架构
内容来源
Doris 深度笔记

预计阅读时间: 30 分钟 | 前置阅读: doc-00 §2, doc-06 (Tablet) 下一次阅读: doc-13 (RPC)


1. 副本模型与 Version 一致性

Tablet 0 (3 副本):
  Replica A (BE-1): version=10, visible_version=10  ← 最新
  Replica B (BE-2): version=9, visible_version=9    ← 延迟 (Publish未到)
  Replica C (BE-3): version=10, visible_version=10  ← 最新

查询: Coordinator 选择副本 A 或 C 执行 (跳过 B, 因为 version 低)
写入: all 3 副本同时写入 (写到 MemTable + Flush)

Version 一致性保证: 写入必须所有副本成功后才 Publish。如果某个副本写入失败 → FE 重新分配写入到其他 BE (重试), 失败副本标记为不可用。


2. TabletChecker → TabletRepair——修复调度

调度流程

TabletChecker (FE, 定期运行, 每 60s)
  → 1. 检查每 Tablet 的副本数: expected_replica_num (默认3) vs actual
  → 2. 检查每副本的版本: max_version vs visible_version
  → 3. 检查每副本的状态: ALIVE / DECOMMISSION / SCHEMA_CHANGE
  → 4. 生成 TabletRepair 任务 (需要修复的 Tablet)
  → 5. 加入 TabletScheduler 队列

TabletScheduler (FE, 后台线程)
  → 1. 从队列取 TabletRepair 任务
  → 2. 优先级: HighPriority (急需修复) > Normal > Low (均衡/迁移)
  → 3. 选择目标 BE (健康+有空间+负载低)
  → 4. 发起 Clone: Src BE (源副本) → Dst BE (新建副本)
  → 5. Clone 完成 → FE 更新 Catalog (Replica added)

源码导航

文件关键类/方法职责
fe/fe-core/.../clone/TabletScheduler.javaTabletScheduler.addTablet(), scheduleTablet()修复任务调度
fe/fe-core/.../clone/TabletChecker.javaTabletChecker.checkTablets()定期检查副本状态
fe/fe-core/.../catalog/Replica.javaReplica.getVersion(), ReplicaState副本元数据
be/src/agent/task_worker_pool.cppCloneWorkerPoolBE 端 Clone 执行
be/src/storage/tablet_manager.cppTabletManager::create_tablet()BE 端 Tablet 创建
be/src/storage/snapshot_manager.cppSnapshotManager快照打包/传输

BE 副本一致性与修复 图 01

3. Clone 流程——副本迁移/修复/均衡

全流程

FE: TabletScheduler 发起 Clone
  → 1. 选择 Src Replica (version 最新的健康副本)
  → 2. 选择 Dst BE (目标 BE=健康的, 有磁盘空间)
  → 3. BE Agent RPC: CloneReq(src_replica, dst_tablet)

    Src BE:
      → 4. 快照 (Snapshot): 将 Tablet 的 Rowset 文件打包
      → 5. 传输到 Dst BE (HTTP File Transfer / 硬链接)

    Dst BE:
      → 6. 解包 Snapshot → 创建 Tablet 目录 + Rowset 文件
      → 7. 加载 Rowset 到本地 Tablet 实例
      → 8. 更新 Tablet Meta → 上报 FE

  → 9. FE 收到 Clone 完成通知
  → 10. FE Catalog: 添加新 Replica (src version, src state)
  → 11. Dst Replica 开始正常服务查询和写入

Clone 类型

类型触发条件优先级
RepairTablet 副本数 < expected_replica_numHIGH
Version Incomplete副本 version 落后太多HIGH
Replica RelocationBE 磁盘使用不均 (平衡)LOW
BE DecommissionBE 节点安全下线NORMAL

4. 常见问题 / 面试题

Q1: Clone 过程中, Tablet 能继续写入吗? A: 能。Clone 是对 Src Replica 的某个时间点快照, 快照后 Src 的写入不受影响。Dst 收到快照后, 通过回放快照后的增量 Journal (version diff) 追上最新版本。

Q2: 如何避免 Clone 过程中占用过多磁盘/网络资源? A: 并发控制: TabletScheduler 限制同时运行的 Clone 任务数; Rate Limiter 限制传输速度 (clone_worker_count, clone_bandwidth); 低优先级 IO。

Q3: 3 副本写入了 2 个成功, 1 个失败——查询时能读到数据吗? A: 写入成功的 2 个副本 Publish 后变为可见(查询可读), 失败的副本延迟 Publish。Coordinator 选择成功的副本执行查询。失败副本后续通过 Repair 修复。


BE 副本 Clone 修复流程

下一步