当主地域光缆中断,如何自动提升从端为“write”角色?
解读
面试官真正想考察的是:
- 你是否理解 CouchDB 多主(multi-master) 架构下“写角色”并非传统 MySQL 的主从切换,而是节点写可用性的恢复;
- 在国内“两地三中心”合规场景里,光缆中断=跨省 BGP 路由收敛时间≥180 s,如何做到业务侧无感;
- 你是否能给出可落地的自动化方案,而不是背文档。
一句话:光缆断了,如何让异地节点秒级接受新写流量,且数据收敛后冲突可解。
知识点
-
CouchDB 3.x 集群仲裁
- 节点数必须≥3,且存活节点>(n/2) 才能选出新“write” coordinator;
- 国内常见 3 节点同城双活+1 节点异地冷备,光缆断后异地节点因无法凑够仲裁默认拒绝写,需人工介入。
-
q=8/n=3 分片副本策略
- 每个分片 3 副本,至少 2 副本在线才允许写;
- 若主地域 2 副本同时失联,剩余 1 副本自动降级为只读,必须强制提升。
-
国内网络特征
- 跨省链路经常走国家级骨干网,中断后 BGP 收敛 3~5 min,心跳超时需>300 s 避免误切;
- 部分省间链路存在单向丢包,需双向探测。
-
自动化工具链
- CouchDB 自身无内建“failover”,需外部脚本或 Kubernetes Operator;
- 常用组合:Consul-Terraform + Ansible + CouchDB http api;
- 强制提升接口:
PUT /_node/_local/_config/cluster/force_membership+PUT /_cluster_setup完成节点角色变更。
-
数据冲突与业务补偿
- 多主写冲突靠revision tree自动合并,国内金融场景需业务层幂等键兜底;
- 光缆恢复后启动resync-smart(CouchDB 3.3 特性)做增量对齐,避免全量复制占满 30 M 小水管。
答案
给面试官一个可落地的三阶段回答,时间控制在 3 分钟:
阶段 1:预防
- 集群采用 5 节点布局:主地域 3 节点(同城双 AZ),异地 2 节点(不同省),q=8/n=3;
- 把
cluster_quorum参数显式设为3,心跳超时 35 s、重试 5 次,防止 BGP 抖动误切; - 每个节点内置 consul-agent,通过 TTL+TCP 双向探测判定“真正”光缆中断。
阶段 2:自动提升
- 当 consul 健康检查连续 3 次失败(约 105 s)且主地域节点<3,触发 Ansible Playbook;
- Playbook 步骤:
① 通过 VPN 带外通道登录异地任意节点,执行
curl -X PUT http://127.0.0.1:5984/_node/_local/_config/cluster/force_membership -d '"true"'
强制把剩余节点声明为合法集群;
② 调用/_cluster_setup完成新仲裁,把 n=3 临时降为 n=2,写权限立即开放;
③ 在阿里云 DNS 将 CNAME 切到异地 SLB,TTL 预置 30 s,实现业务侧秒级切换;
④ 通过钉钉/飞书 webhook 发送“光缆中断+自动提升完成”告警,附带当前cluster_nodes与active_nodes列表,方便合规审计。
阶段 3:恢复与回切
- 光缆修复后,先让主地域节点以 read-only 模式启动,执行
resync-smart追平增量; - 确认 revision 差值<1000 且 checkpoint 一致后,再把 n=2 改回 n=3,最后把 DNS 切回主地域;
- 全程记录 Operation ID,满足国内金融合规“双录”要求。
一句话总结:用 5 节点+consul 仲裁,105 s 内自动降副本并强制提升,DNS 30 s 切换,光缆恢复后增量回切,冲突用 revision tree+业务幂等键兜底。
拓展思考
- 如果合规要求 RPO=0,上述方案在光缆断瞬间仍可能丢失未复制写,可引入 Kafka MirrorMaker 做跨地域双写日志,CouchDB 仅作为最终存储,实现写前日志多活。
- 在 K8s 场景,可用 CouchDB-Operator 2.2 的
autoFailover: true字段,把上述脚本封装为 CRD,Pod 级故障 40 s、节点级故障 90 s 自动触发,减少 Ansible 维护成本。 - 对于 跨省 5G 边缘节点,链路质量更差,可把心跳探测改为 QUIC+MTLS,在 200 ms 内感知丢包,提前 80 s 触发提升,进一步降低业务中断时间。