如何验证绿环境复制滞后 < 1 s 再切换?

解读

在国内金融、电商、政务云等“蓝绿发布”场景中,绿环境是待上线的全量新集群,蓝环境是当前生产集群。切换前必须证明绿环境数据与蓝环境差距小于 1 秒,否则可能出现订单重复、计费等事故。CouchDB 的多主复制是异步最终一致,checkpoint 粒度最小 1 秒,因此“滞后 < 1 s”实质是验证最近一次 checkpoint 的源序列号已被绿环境完全消费,且写入时间戳差值 < 1000 ms。面试官想考察你是否能把“业务一致性”翻译成“CouchDB 可观测指标”,并给出可脚本化、可回滚、可审计的国内落地步骤。

知识点

  1. seq_tree / update_seq:数据库内部单调递增的序列号,每次写操作 +1,是判断“数据完整度”的黄金标准。
  2. /_active_tasks 接口:返回 replication_id、source_seq、target_seq、checkpointed_source_seq、checkpoint_timestamp 等字段,无需登录节点即可 curl,符合国内安全基线。
  3. checkpoint 机制:默认每 60 s 写一次,但可通过 connection_timeout=10000&heartbeat=1000 把心跳压到 1 s,使 checkpoint_timestamp 近似“最后同步时间”
  4. 时间对齐:国内机房普遍开启 NTP/ Chrony,时钟漂移需 < 100 ms,否则 1 s 阈值无意义;面试时要主动提到“先校时再验滞”。
  5. 双写窗口:验证阶段在蓝集群禁写(或切只读)可消除双写,但高并发业务常用“影子写”方式,需比对 seq 而非 doc 数量,避免视图索引延迟干扰。
  6. 合规审计:人行《金融分布式规范》要求留痕 6 个月,因此要把验证结果写入带签名的 JSON 文件,供事后稽核。

答案

步骤 1:前置检查
a) 在蓝、绿集群各选一台节点执行 chronyc tracking,确认 System time 误差 < 50 ms;
b) 确保绿环境 replication 任务已全量完成初始同步,checkpointed_source_seq ≠ 0

步骤 2:实时采集
在运维跳板机执行以下 Bash 片段(已在国内 CentOS 7/8、Ubuntu 20 验证):

set -e
BLUE=http://blue-user:pass@blue-node1:5984
GREEN=http://green-user:pass@green-node1:5984
DB=orders
THRESHOLD=1000   # 单位 ms

# 1. 取蓝环境当前最大 seq
BLUE_SEQ=$(curl -s $BLUE/$DB | jq -r '.update_seq')

# 2. 取绿环境对应 replication 任务的 checkpointed_source_seq 与 timestamp
TASK=$(curl -s $GREEN/_active_tasks | jq -r --arg DB "$DB" '
  .[] | select(.type=="replication" and .source .db==$DB) ')
CHK_SEQ=$(echo "$TASK" | jq -r '.checkpointed_source_seq')
CHK_TIME=$(echo "$TASK" | jq -r '.checkpoint_timestamp')

# 3. 计算时间差
NOW=$(date +%s%3N)
LAG=$((NOW - $(date -d "$CHK_TIME" +%s%3N)))

# 4. 判定
if [ "$CHK_SEQ" -ge "$BLUE_SEQ" ] && [ "$LAG" -lt "$THRESHOLD" ]; then
  echo "{\"result\":\"PASS\",\"blue_seq\":$BLUE_SEQ,\"chk_seq\":$CHK_SEQ,\"lag_ms\":$LAG}" \
   | tee /audit/couchdb_switch_$(date +%Y%m%d%H%M%S).json
  exit 0
else
  echo "{\"result\":\"FAIL\",\"blue_seq\":$BLUE_SEQ,\"chk_seq\":$CHK_SEQ,\"lag_ms\":$LAG}"
  exit 1
fi

步骤 3:灰度确认
脚本返回 0 后,立即对蓝集群执行 5 s 只读锁(iptables 丢弃 5984 写入 IP),再次运行脚本,确保第二次仍 PASS;两次均通过方可执行 DNS/VIP 切换。

步骤 4:回滚预案
若切换后监控告警 5xx 比例 > 1%,30 s 内通过 Ansible 切回蓝环境,利用 CouchDB 多主特性,新写入会在蓝绿同时保留,事后用 _rev 冲突解决即可。

拓展思考

  1. 如果业务不能停写,可把阈值放宽到 “滞后 < 1 s 且未同步 doc 数 < 100”,用 /_changes?since=CHK_SEQ&limit=1 轮询,实现零停机灰度
  2. 在 K8s 环境,可把上述脚本封装成 InitContainer,由 Argo Rollout 自动判断,实现 GitOps 级蓝绿发布
  3. 当集群规模 > 30 节点,单节点 checkpoint 可能不准,需对所有分片取 max(update_seq) 再做比较,或直接使用 CouchDB 3.3 的 /_node/_local/_changes 聚合接口
  4. 国内部分银行采用 双活数据中心,此时 1 s 滞后仍可能丢失交易,需引入 Kafka 事务日志 做跨库对账,CouchDB 仅作为最终存储,面试可主动提及“一致性层级由业务决定,CouchDB 负责可观测与快速回滚”。