4、分布式事务基础:ACID 理论、CAP 定理、BASE 理论
聊 Exactly Once 语义,绕不开分布式事务。很多同学一听到「分布式事务」就头大,觉得这东西又慢又复杂。说实话,我早年也有这感觉。直到在线上环境被数据不一致坑过几次,才老老实实把基础补上。
这一章,咱们把三个最核心的理论掰开揉碎。ACID、CAP、BASE。它们不是教科书上的死概念,而是你设计系统时的「决策框架」。
4.1 ACID:单机数据库的「铁律」
ACID 是单机数据库的基石。你想想看,一个银行转账场景,A 扣 100,B 加 100。要么都成功,要么都失败。这就是事务。
| 特性 | 含义 | 我踩过的坑 |
|---|---|---|
| 原子性 (Atomicity) | 事务要么全做,要么全不做 | 曾经在批量扣款时,中间一条失败,前面的已经提交了…… |
| 一致性 (Consistency) | 事务前后,数据满足所有约束 | 这个更多是业务逻辑的事,数据库只管约束 |
| 隔离性 (Isolation) | 并发事务互不干扰 | 默认的 Read Committed 级别,在账务系统里根本不够用 |
| 持久性 (Durability) | 提交后,数据不会丢 | MySQL 双 1 配置,刷盘是必须的 |
我个人习惯把 ACID 理解成「单机事务的黄金标准」。在单体架构里,它非常好用。但到了分布式环境,你没法让所有节点都保持强一致,否则性能会崩。
4.2 CAP 定理:分布式系统的「不可能三角」
CAP 定理是分布式系统的「紧箍咒」。它说:一个分布式系统,最多只能同时满足 C、A、P 中的两个。
- C (Consistency) 一致性:所有节点在同一时刻看到的数据是一样的。
- A (Availability) 可用性:每个请求都能收到一个响应(不保证数据是最新的)。
- P (Partition Tolerance) 分区容错性:系统内部分节点之间通信断了,系统还能继续工作。
为什么是「不可能三角」?我举个例子。假设两个节点 A 和 B,中间网络断了(分区发生)。这时候你写数据到 A,B 是不知道的。
- 如果你选 CP:那 B 必须拒绝所有读请求,直到网络恢复。保证了数据一致,但牺牲了可用性。
- 如果你选 AP:那 B 可以继续返回旧数据。保证了可用性,但数据可能不一致。
说白了,P 是必选的。因为网络分区一定会发生。你只能在 C 和 A 之间做取舍。
我记得在做一个订单系统时,我们选了 AP。用户下单后,立即返回成功,但后台异步对账。结果有一次网络抖动,订单状态在数据库里乱掉了。嗯,那之后我们加了一层补偿机制。
4.3 BASE 理论:向现实妥协的「柔性事务」
BASE 理论是 eBay 的架构师 Dan Pritchett 提出的。它是对 CAP 中「AP」路线的一种实践总结。
| 缩写 | 全称 | 解释 |
|---|---|---|
| BA | Basically Available | 基本可用。系统允许部分功能降级,比如双十一时,查询订单可以延迟几秒 |
| S | Soft State | 软状态。数据允许中间状态,比如「支付中」「待确认」 |
| E | Eventually Consistent | 最终一致。经过一段时间后,所有数据会达成一致 |
你想想看,BASE 其实就是放弃了 ACID 的强一致性,换来了更高的可用性和扩展性。它不要求数据时刻一致,只要求「最终一致」。
4.4 三者的关系与选择
ACID、CAP、BASE 不是互斥的,而是不同场景下的不同选择。
- 单机场景:用 ACID,简单可靠。
- 分布式场景,要求强一致:选 CP,比如 Zookeeper、Etcd。
- 分布式场景,要求高可用:选 AP + BASE,比如大部分互联网业务。
我建议你在设计系统时,先问自己三个问题:
- 这个数据允许不一致多久?
- 不一致了,能自动修复吗?
- 用户能接受偶尔的延迟或降级吗?
回答完这三个问题,你自然就知道该选哪条路了。
4.5 知识体系图
下面这张图,帮你理清这三个理论的关系和适用场景。
这张图从左到右,展示了从单机到分布式的演进路径。ACID 是起点,CAP 是约束,BASE 是解法。你不需要死记硬背,理解每个理论的「为什么」和「什么时候用」,比背概念重要得多。