数据一致性模式:后端微服务的必修课

198 阅读3分钟

1. 背景

在单体系统中,数据库通常是单一实例,事务(ACID)能保证强一致性。
但在 微服务 + 分布式系统 中:

  • 数据分散在不同服务(订单、库存、支付等)
  • 不同数据库(MySQL、Redis、MongoDB 等)
  • 跨网络通信,不可避免有延迟、失败、重试

👉 结果是:强一致性难以保证
因此,后端工程师必须掌握 数据一致性模式 来保证业务正确性。


2. 一致性模型回顾

  • 强一致性(Strong Consistency) :所有副本数据在同一时刻相同。
  • 最终一致性(Eventual Consistency) :经过一段时间,副本数据最终一致。
  • 因果一致性(Causal Consistency) :保证有因果关系的操作顺序一致。

微服务架构下,大部分场景采用 最终一致性,通过补偿和事件机制来保证。


3. 常见的一致性模式

3.1 两阶段提交(2PC, Two-Phase Commit)

  • 原理:协调者先“准备”,所有参与者同意后再“提交”。
  • 优点:接近强一致性。
  • 缺点:阻塞、性能差、单点故障。
  • 适用场景:少数强一致性要求极高的分布式事务。

3.2 Saga 模式

Saga 是 长事务拆分 + 补偿 的思路:

  • 将全局事务拆成一系列本地事务,每个事务有对应的补偿操作。
  • 如果中途失败,执行补偿事务撤销之前的操作。

例子:下单流程

  1. 订单服务 → 创建订单
  2. 库存服务 → 扣减库存
  3. 支付服务 → 扣款
    ❌ 如果支付失败 → 触发补偿:库存回滚、订单取消。

👉 Saga 可以通过 事件驱动集中编排(Orchestrator) 实现。


3.3 TCC 模式(Try-Confirm-Cancel)

  • Try:预留资源(冻结库存、预扣款)
  • Confirm:真正提交
  • Cancel:取消预留

适合对资源一致性要求更高的场景(金融转账、机票预定)。


3.4 Outbox Pattern

为了解决“本地事务 + 事件发送”不一致的问题:

  • 把事件和业务数据写入同一个数据库事务(Outbox 表)。
  • 由异步任务(CDC 或定时器)将事件发送到消息队列。
  • 保证业务操作和事件投递要么同时成功,要么同时失败。

👉 常见在 Kafka + MySQL 场景。


3.5 基于事件的最终一致性

  • 使用 Kafka / Pulsar 等消息队列传递事件。
  • 消费者异步处理,保证最终一致性。
  • 通过幂等性、重试机制保证可靠。

4. 实践要点

  • 幂等性设计

    • 数据库操作使用 UPSERT
    • API 使用全局请求 ID 去重
  • 补偿机制

    • Saga、TCC 必须有对应的 Cancel/Compensate 流程
  • 监控与告警

    • 一致性问题往往不是完全自动可解,需要监控 + 人工介入
  • 事务边界

    • 明确哪些操作必须强一致,哪些可以最终一致

5. 应用场景

电商系统

  • 下单 → 库存 → 支付 → 物流
  • 常用 Saga 或 Outbox

金融系统

  • 转账 → 扣款 + 入账
  • 常用 TCC,保证资金安全

SaaS 平台

  • 用户订阅服务 → 开通功能 → 发放优惠券
  • 常用事件驱动 + 最终一致性

6. 对比总结

模式一致性性能复杂度典型场景
2PC强一致跨库事务
Saga最终一致电商订单
TCC接近强一致金融转账
Outbox最终一致事件驱动
事件驱动最终一致微服务解耦

7. 总结

在分布式后端架构中:

  • 不存在万能方案,一致性模式必须结合业务权衡。
  • 高并发、高可用的系统往往依赖 Saga + Outbox + 幂等性
  • 对安全性要求极高的系统(金融)则会采用 TCC 或部分 2PC

👉 一句话总结:
强一致性很昂贵,最终一致性更常见,但需要工程上精心设计补偿与幂等。