如何基于“/_partition/{partition}/_changes”快速验证热点?

解读

国内 CouchDB 面试常把“热点”定义为:某一 partition key 下的写操作频率远高于其他分区,导致 seq 增长过快、磁盘 I/O 倾斜、复制积压 等现象。
面试官真正想考察的是:

  1. 你是否知道 /_partition/{partition}/_changes 只能返回该分区的有序变更流,天然适合做“分区级”热点探测;
  2. 能否用 seq 差值 + 时间窗口 在秒级内给出量化结论;
  3. 是否具备 线上可落地 的脚本思路,而不是照搬文档。

知识点

  • /_partition/{partition}/_changes 返回该分区自给定 since 以来的变更数组,每条含 seq、id、changes、deleted 字段;
  • seq 是数据库级全局序列号,但在同一分区内严格递增,因此 Δseq/Δt 可直接换算为“该分区写 QPS”;
  • last_seqpending 字段可用来判断“是否已追平实时”,避免读历史数据时误判;
  • 国内机房常用 内网千兆,一次拉取 1 万条变更约 1.2 MB,curl+jq 即可在 200 ms 内完成,无需额外组件;
  • 若发现 Δseq/Δt > 阈值(如 500 笔/s),可立即用 /_partition/{partition}/_all_docs?startkey_docid=xxx&limit=10 抽样文档 id,确认是否来自同一业务 key,进而定位“热点写”。

答案

线上 5 步快速验证:

  1. 取当前秒级时间戳 T1,记录 since=now 对应的 seq1
    curl -s -u user:user:pass 'http://内网IP:5984/db/_partition/2023-04/_changes?limit=1' | jq -r '.last_seq'
  2. 等待 N 秒(国内经验值 5 s,既不过于敏感,又能快速反馈);
  3. 再次拉取,得 seq2
  4. 计算 Δseq = seq2 - seq1,若 Δseq / N > 业务阈值(如 500),即判定该分区为热点;
  5. 为排除“历史积压”,追加判断 pending == 0,确保两次采样都在实时流上。
    整套脚本可在 跳板机 用一行 shell 完成,耗时 <10 s,对线上零影响。

拓展思考

  • 若分区键设计为 “用户尾号”,发现尾号 06 热点后,可临时在应用层 降级缓存双写新分区 06_bak,实现秒级止血;
  • 跨机房复制 场景,可对比源集群与目标集群的 同一分区 seq 差值,若差值持续拉大,说明热点已引发 复制 lag,需调高 worker_processescheckpoint_interval
  • 国内金融合规要求 审计留痕,可把该脚本嵌入 Crontab,每 30 s 采样一次,seq 增量直接写入 Elasticsearch,通过 Kibana 仪表盘 实现“分区级写热点”实时告警,满足 等保 2.0 对“异常行为监测”条款。