解释“checkpoint”滑动窗口机制如何防止重复传输已同步文档?

解读

在国内 CouchDB 面试中,这道题考察的是你对多主复制协议的深层理解,尤其是增量同步容错恢复环节。面试官想确认你是否知道:

  1. 节点之间如何只传差异数据而不重传整库;
  2. 当网络闪断或进程重启后,如何快速续传
  3. 滑动窗口如何平衡内存占用与传输效率
    答出“seq 区间 + 摘要对比 + 窗口滑动”三板斧,即可拿到高分。

知识点

  1. seq_index(更新序列号):每个数据库实例维护一个单调递增的 seq 计数器,文档每次变更即产生新 seq。
  2. checkpoint 文档:同步结束后,目标节点会在本地 _local/{sourceUUID} 文档里记录最后连续确认的 seq摘要哈希,作为下一次同步的“起点”。
  3. 滑动窗口:源节点把 seq 区间拆成可配置大小(默认 100)的批次,逐批推送;每成功一批,窗口向前滑动,释放内存。
  4. 摘要对比:窗口内若检测到目标节点已拥有某文档(通过 rev 树与哈希比对),则跳过传输,仅更新 seq 指针,实现去重
  5. 容错续传:网络中断后,源节点读取目标节点的 checkpoint,从断点 seq 继续拉取,避免全量重扫。

答案

CouchDB 的 checkpoint 滑动窗口机制通过“seq 区间 + 批次确认 + 摘要去重”三步防止重复传输:

  1. 启动同步时,源节点先读取目标节点_local 空间下的 checkpoint 文档,拿到上次成功同步的最大 seq
  2. 以该 seq 为起点,把待同步的变更按**窗口大小(默认 100)**划分批次,逐批发送;
  3. 每批到达后,目标节点用rev 树与摘要哈希快速判断文档是否已存在:若存在则仅回写确认 seq,不落地数据;
  4. 当一批全部确认,窗口向前滑动,源节点更新本地内存指针,并异步写回新的 checkpoint;
  5. 若中途掉线,重启后双方再次读取最新 checkpoint,即可从断点续传,既节省带宽,又保证 exactly-once 语义。

拓展思考

  1. 窗口大小调优:国内公有网 2 Mbps 小水管场景,可把 window 降到 20,减少超时;内网万兆环境可放大到 1000,提升吞吐。
  2. 冲突积压风险:若业务热点 key 频繁冲突,rev 树会膨胀,导致摘要对比 CPU 飙高,可配合_revs_limit 参数裁剪历史。
  3. 多源并发:同一目标被 A、B 两源同时写入时,checkpoint 文档以源节点 UUID 为键隔离,互不覆盖,实现多路并行续传
  4. 监控指标:建议把checkpoint 滞后 seq 数滑动窗口重试次数接入 Prometheus,提前发现“假死”同步链路,避免国内客户业务高峰期的跨省跨云同步雪崩