Yihui’s Blog

如何设计高可用数据同步系统?需要哪些容错机制?

日期:2026-07-12
标签:#面试 #八股 #后端 #数据同步 #高可用 #系统设计

一句话答案

通过无单点部署、持久消息、租约选主、检查点、幂等写入、重试死信、背压限流、对账补数和灾备演练,使任一组件故障后可恢复且不破坏数据正确性。

面试口语版

采集器多实例候选但同一分片只允许一个 Leader,通过租约和 fencing token 防双读;位点写高可用状态存储。中间使用多副本 MQ 持久化,保留足够回放窗口。计算任务使用 checkpoint 和状态后端,失败自动重启;Sink 采用幂等 upsert 或两阶段提交。网络和目标库故障时指数退避、暂停消费并形成背压,不能无限读源;坏数据进隔离/死信队列。全链路监控 Lag、吞吐、错误、checkpoint 和数据质量,定期对账与补数,并演练 Broker、节点和机房故障。

容错矩阵

故障机制
采集器宕机租约接管、位点恢复
MQ 节点故障多副本、确认、保留回放
计算失败Checkpoint、自动重启
Sink 超时幂等重试、熔断、背压
坏数据隔离队列、人工修复
静默漏数对账、补数、离线重算

关键细节

  • Exactly-once 是端到端属性,不能只看 Flink 开关。
  • 故障恢复时间必须小于 MQ/日志保留时间。
  • 双活会引入写冲突,需明确单一数据所有者。
  • 降级不能静默丢数据,要暴露状态和审计。

面试官追问

  1. 如何避免采集器双主重复读取?
  2. 下游长时间不可用怎么办?
  3. 如何发现没有报错但已经漏数?

面试官追问参考答案

1. 如何避免采集器双主重复读取?

协调系统为分片分配租约和单调 Epoch,只有当前 Epoch 可提交位点;旧实例恢复后的写入被状态存储拒绝。即使短暂重复读取,后续事件 ID/位点幂等也能消除副作用。

2. 下游长时间不可用怎么办?

暂停或限速消费,让数据留在持久 MQ,监控保留空间和预计恢复时间;必要时扩容存储或旁路归档到对象存储。业务定义最大延迟和降级,恢复后限速追赶,避免再次压垮下游。

3. 如何发现没有报错但已经漏数?

按时间窗口、分片和业务主键比较源端与目标的条数、金额、最大位点和校验和,建立数据质量 SLI。抽样明细和离线全量对账发现静默错误,并自动生成补数任务。

学习清单

  • 能按组件列出容错机制。
  • 理解恢复、背压和静默数据错误。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts