解释“delta-sync”实验特性的原理及当前版本限制。

解读

国内面试官问“delta-sync”,并不是想听一句“只传差异数据”就结束,而是考察候选人是否真正踩过 3.x 的坑

  1. 是否理解 CouchDB 复制协议在全量 rev 树广播阶段的性能瓶颈;
  2. 是否知道 delta-sync 如何用**默克尔哈希树(Merkle Trie)**把 rev 树切成“切片”并只传差异;
  3. 是否清楚该特性在** 3.2.2-3.3.x** 仍标为“experimental”,生产落地必须接受哪些限制;
  4. 能否给出灰度切换方案回退命令
    答不到“切片哈希”“回退”“禁用”三个关键词,基本会被判定为“只看过博客”。

知识点

  1. 传统复制流程:源端先广播整个** rev 树**,目标端比对后拉取缺失文档;rev 树过大时带宽与 CPU 都浪费。
  2. delta-sync 原理:
    • 把每个 db 分片内的 rev 树再拆成** 8 k 文档切片**;
    • 对切片计算滚动哈希(Rabin)+ BLAKE2b,得到默克尔节点;
    • 复制时只交换根哈希路径不同的切片,再传输切片内真正的差异 rev;
    • 切片级缓存放在** .couch 目录下的 delta_sync/ 子目录**,重启后复用。
  3. 启用方式:
    • 节点级:[replicator] delta_sync = true
    • 单次复制:PUT /_replicator/job 时在 JSON 里加 "delta_sync": true
  4. 当前版本(3.3.2)限制:
    • 仅支持单向拉动(pull);推(push)仍回退全量;
    • 源与目标哈希算法版本必须一致,否则自动回退;
    • 切片缓存默认上限 1 GB,超限时整库回退全量同步;
    • 与**压缩附件(compression=att_encoding)**同时开启时会被拒绝;
    • 实验标志位:集群任一节点关闭该特性,整个复制链回退;
    • 官方文档明确提示:不要在生产关键业务开启,除非可接受回退窗口
  5. 监控与回退:
    • 监控:/_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 观察回退率,确认稳定后再扩大范围,并保留随时热关闭的能力。

拓展思考

  1. 如果业务库平均文档 2 kB,但 rev 树深度高达 200,delta-sync 收益是否一定显著?
    答:不一定。深度过大导致切片数量爆炸,哈希比对 CPU 可能反超省下的带宽,需要实测 bytes_saved / fallbacks 比值。
  2. 国内多云混合场景,跨云专线带宽 20 Mbps、RTT 120 ms,如何评估是否启用?
    答:先用 /_replicate 做 5 分钟采样,对比 delta_sync=true/false 时的 goodputfallback 次数,若带宽节省 >30% 且回退率 <1%,可灰度;否则继续调大 delta_cache_size 或放弃。
  3. 未来 4.x roadmap 已提出“双向 delta-sync + 压缩切片”,作为架构师你现在应预留哪些接口?
    答:
    • 在 CI 里把复制任务配置抽象成模板,支持特性开关
    • 监控指标统一打到 Prometheus,标签带上 delta_sync_version
    • 切片缓存目录单独挂载 SSD,并做容量告警,方便 4.x 直接升级算法版本而无需重新全量同步。