ADR-003: 使用 FastCDC 替代固定分块
状态
已采纳
背景
大文件需要分块存储以支持:
- 增量同步(只传输变化的块)
- 去重(相同内容的块只存一次)
- 流式处理(内存恒定)
分块策略的选择直接影响去重效率和同步带宽。
决策
使用 FastCDC(Content-Defined Chunking)替代固定大小分块。
考虑的选项
1. 固定大小分块(4MB)
优点:
- 实现简单
- 块大小可预测
缺点:
- 插入/删除导致后续所有块哈希变化
- 去重效率低(相似文件很少能匹配)
- 同步时传输大量无效数据
示例:在文件开头插入 100B
固定分块(4MB):
原始: [Block1][Block2][Block3][Block4]...
插入后: [Block1'][Block2'][Block3'][Block4']...
↑ 所有块哈希都变了!
需要重新上传整个文件。2. FastCDC(选中)
优点:
- 内容定义边界:插入/删除只影响局部
- 去重率提升 30%+
- 增量同步带宽减少 90%+
缺点:
- 实现稍复杂
- 块大小不固定(但在范围内)
示例:在文件开头插入 100B
FastCDC(avg 4MB):
原始: [Block1][Block2][Block3][Block4]...
插入后: [Block1'][Block2][Block3][Block4]...
↑ 只有第一个块变化!
只需上传 ~4MB。3. Rabin 指纹
优点:
- 经典的 CDC 算法
缺点:
- 性能较低
- FastCDC 是其优化版本
性能对比
| 场景 | 固定分块 | FastCDC | 改进 |
|---|---|---|---|
| 开头插入 1KB | 100% 重传 | ~4MB 重传 | 96% |
| 中间修改 100B | ~50% 重传 | ~4MB 重传 | 92% |
| 相似文件去重 | ~10% | ~99% | 89% |
配置
pub struct ChunkingConfig {
pub min_size: usize, // 2 MB(最小块)
pub avg_size: usize, // 4 MB(平均块)
pub max_size: usize, // 8 MB(最大块)
}后果
优点
- 增量同步高效
- 去重率大幅提升
- 相似文件存储节省空间
缺点
- 块大小不固定,管理稍复杂
- 需要存储块边界信息