解释“delta-sync”实验特性的原理及当前版本限制。
解读
国内面试官问“delta-sync”,并不是想听一句“只传差异数据”就结束,而是考察候选人是否真正踩过 3.x 的坑:
- 是否理解 CouchDB 复制协议在全量 rev 树广播阶段的性能瓶颈;
- 是否知道 delta-sync 如何用**默克尔哈希树(Merkle Trie)**把 rev 树切成“切片”并只传差异;
- 是否清楚该特性在** 3.2.2-3.3.x** 仍标为“experimental”,生产落地必须接受哪些限制;
- 能否给出灰度切换方案与回退命令。
答不到“切片哈希”“回退”“禁用”三个关键词,基本会被判定为“只看过博客”。
知识点
- 传统复制流程:源端先广播整个** rev 树**,目标端比对后拉取缺失文档;rev 树过大时带宽与 CPU 都浪费。
- delta-sync 原理:
- 把每个 db 分片内的 rev 树再拆成** 8 k 文档切片**;
- 对切片计算滚动哈希(Rabin)+ BLAKE2b,得到默克尔节点;
- 复制时只交换根哈希路径不同的切片,再传输切片内真正的差异 rev;
- 切片级缓存放在** .couch 目录下的 delta_sync/ 子目录**,重启后复用。
- 启用方式:
- 节点级:
[replicator] delta_sync = true; - 单次复制:PUT
/_replicator/job时在 JSON 里加"delta_sync": true。
- 节点级:
- 当前版本(3.3.2)限制:
- 仅支持单向拉动(pull);推(push)仍回退全量;
- 源与目标哈希算法版本必须一致,否则自动回退;
- 切片缓存默认上限 1 GB,超限时整库回退全量同步;
- 与**压缩附件(compression=att_encoding)**同时开启时会被拒绝;
- 实验标志位:集群任一节点关闭该特性,整个复制链回退;
- 官方文档明确提示:不要在生产关键业务开启,除非可接受回退窗口。
- 监控与回退:
- 监控:
/_node/_local/_stats/replicator.delta_sync.{fallbacks,bytes_saved}; - 回退:热修改配置为 false,无需重启,正在进行的复制会在下一轮心跳切回全量。
- 监控:
答案
delta-sync 是 CouchDB 3.x 引入的实验性差异同步机制,用于解决传统复制中“全量 rev 树广播”带来的带宽与 CPU 浪费。
核心思路是把每个分片的 rev 树切成** 8 k 文档切片**,对切片构建默克尔哈希树;复制时只比对并传输哈希不一致的切片,再补传切片内缺失的 rev,从而把同步数据量降到“差异”级别。
启用后,切片级缓存保存在本地 delta_sync/ 目录,重启可复用。
但截至** 3.3.2** 该特性仍标为 experimental,主要限制包括:
- 仅支持单向 pull,push 自动回退全量;
- 源目标哈希版本必须一致,否则整库回退;
- 切片缓存默认 1 GB,超限回退;
- 与附件压缩互斥;
- 集群内任一节点关闭则整体回退;
- 官方明确不建议在核心生产直接开启,除非已做好回退预案与指标监控。
落地时应先在灰度集群打开,通过/_stats/replicator.delta_sync.fallbacks观察回退率,确认稳定后再扩大范围,并保留随时热关闭的能力。
拓展思考
- 如果业务库平均文档 2 kB,但 rev 树深度高达 200,delta-sync 收益是否一定显著?
答:不一定。深度过大导致切片数量爆炸,哈希比对 CPU 可能反超省下的带宽,需要实测bytes_saved / fallbacks比值。 - 国内多云混合场景,跨云专线带宽 20 Mbps、RTT 120 ms,如何评估是否启用?
答:先用/_replicate做 5 分钟采样,对比delta_sync=true/false时的 goodput 与 fallback 次数,若带宽节省 >30% 且回退率 <1%,可灰度;否则继续调大delta_cache_size或放弃。 - 未来 4.x roadmap 已提出“双向 delta-sync + 压缩切片”,作为架构师你现在应预留哪些接口?
答:- 在 CI 里把复制任务配置抽象成模板,支持特性开关;
- 监控指标统一打到 Prometheus,标签带上
delta_sync_version; - 切片缓存目录单独挂载 SSD,并做容量告警,方便 4.x 直接升级算法版本而无需重新全量同步。