预计阅读时间: 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.java | TabletScheduler.addTablet(), scheduleTablet() | 修复任务调度 |
fe/fe-core/.../clone/TabletChecker.java | TabletChecker.checkTablets() | 定期检查副本状态 |
fe/fe-core/.../catalog/Replica.java | Replica.getVersion(), ReplicaState | 副本元数据 |
be/src/agent/task_worker_pool.cpp | CloneWorkerPool | BE 端 Clone 执行 |
be/src/storage/tablet_manager.cpp | TabletManager::create_tablet() | BE 端 Tablet 创建 |
be/src/storage/snapshot_manager.cpp | SnapshotManager | 快照打包/传输 |

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 类型
| 类型 | 触发条件 | 优先级 |
|---|---|---|
| Repair | Tablet 副本数 < expected_replica_num | HIGH |
| Version Incomplete | 副本 version 落后太多 | HIGH |
| Replica Relocation | BE 磁盘使用不均 (平衡) | LOW |
| BE Decommission | BE 节点安全下线 | 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 修复。

下一步
- RPC: doc-13-rpc-framework.md——Clone 和其他操作的通信层