基础理论
- ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
- CAP:一致性(Consistency)、可用性(Availability)、分区容忍性(Partition tolerance)。
- BASE:基本可用(Basically Available)、软状态(Soft State)、最终一致性(Eventually Consistent)。
CAP 补充解释
单机数据库的事务满足ACID原则.
- C(一致性):同一时刻,所有节点读到的数据一致(像“单机数据库”一样)。
- A(可用性):每个请求都能在有限时间内返回结果(不一定是最新数据)。
- P(分区容忍性):系统在网络分区(节点间通信中断)时,仍能继续对外提供服务。
在分布式系统里,P 通常是必须面对的现实,因此实际常见取舍是:
- CP:优先一致性,牺牲部分可用性(如分区期间拒绝部分请求)。
- AP:优先可用性,允许短暂不一致,后续再收敛。
- CA:只在“无分区”理想条件下成立,真实分布式环境中很难长期满足。
BASE 补充解释
- Basically Available(基本可用):系统在故障时可做降级(如限流、返回兜底数据),但核心能力尽量可用。
- Soft State(软状态):系统状态允许在一段时间内不是强一致的,状态可随同步过程变化。
- Eventually Consistent(最终一致性):如果没有新的更新,经过一段时间后,所有副本最终会一致。
可以把 BASE 理解为对 ACID 的工程化权衡:
- ACID 更偏向强一致、强约束;
- BASE 更偏向高可用、可扩展、可恢复(通过异步、重试、补偿等手段实现最终一致)。
常见讨论
CAP 可以证明吗?
可以。CAP 在形式化模型下是可证明的“不可能性结论”:在异步网络且可能发生网络分区时,系统无法同时严格满足强一致(C)与强可用(A)。
更准确地说:发生分区时,必须在 C 和 A 之间取舍。
BASE 是不是对 C 和 A 都做了妥协?
是。BASE 同时对两者做工程化降级:
- 对 C:从强一致放宽到最终一致。
- 对 A:从“始终成功”放宽到“基本可用”(允许降级、限流、兜底)。
如果追求强可用会怎样?
在分区场景下通常走向 AP:
- 系统优先快速响应,可能返回旧数据;
- 允许短暂不一致,后续通过重试、补偿、冲突合并收敛;
- 业务层需要更强的幂等、去重、版本控制能力。
2PC 是不是强一致?
是,2PC 的目标是保证原子提交(要么都提交,要么都回滚),属于提交层面的强一致;但代价是可用性下降,故障时可能阻塞并长期占用资源。
CP / AP 代表性方案与 CAP 落地
CP(优先一致性 + 分区容忍)
常见理论与产品:
- Raft(理论/协议):通过 Leader + 多数派提交日志保证线性一致;分区时只有多数派侧可写,少数派会拒绝写请求。
- Paxos(理论/协议):以多数派达成共识,确保同一轮只产生一个被接受的值;分区时牺牲部分可用性。
- etcd(产品):基于 Raft 的强一致 KV;网络分区或失去多数派时,写入会失败或阻塞,优先保证一致性。
- ZooKeeper(产品):ZAB 协议,本质同样依赖多数派;失去法定人数时不可写。
它们利用 CAP 的方式:
- 接受 P 必须存在;
- 在分区发生时明确选择 C > A;
- 通过多数派机制把“不可用范围”限制在少数派侧。
AP(优先可用性 + 分区容忍)
常见产品与路线:
- Dynamo / Dynamo 风格系统(理论与实践):分区时优先接受请求,依赖后续副本同步收敛。
- Cassandra(产品):可调一致性级别,低一致性级别下优先可用;结合 hinted handoff、read repair、anti-entropy repair 达到最终一致。
- Riak(产品):分区期间保持服务可用,通过向量时钟/冲突合并实现最终一致。
- CouchDB(产品):多主复制,冲突检测后由应用或策略合并,追求高可用与离线容忍。
它们利用 CAP 的方式:
- 接受 P 必须存在;
- 在分区发生时明确选择 A > C;
- 通过异步复制、冲突检测/合并、补偿机制实现最终一致。
2PC(两阶段提交)
两阶段提交(Two-Phase Commit, 2PC)是一种经典的分布式事务协议,用于确保多个分布式系统中的操作要么全部成功,要么全部失败,保证数据一致性。
流程
准备阶段(Prepare Phase)
协调者(Coordinator)向所有参与者(Participant)发送准备提交请求(prepare)。
参与者执行本地事务操作,但不提交,只写入预提交日志,并锁定相关资源。
参与者将执行结果(可以提交/不能提交)反馈给协调者。提交阶段(Commit Phase)
- 如果所有参与者都反馈“可以提交”,协调者向所有参与者发送提交(commit)请求,参与者正式提交本地事务,释放资源。
- 如果有任何一个参与者反馈“不能提交”或超时未响应,协调者向所有参与者发送回滚(rollback)请求,参与者回滚本地事务,释放资源。
预留资源} B -- 所有Try成功 --> C[各参与者Confirm阶段
正式提交] C --> D[事务完成] B -- 有Try失败或超时 --> E[各参与者Cancel阶段
释放资源/回滚] E --> D
优缺点
- 优点:实现简单,能保证强一致性。
- 缺点:同步阻塞,性能较低;协调者单点故障会导致参与者长时间锁定资源,存在阻塞和脑裂风险。
2PC 常用于分布式数据库、消息队列等场景。实际生产环境中,通常会用 TCC、SAGA 等更灵活的方案来替代 2PC。
3PC(三阶段提交)
三阶段提交(Three-Phase Commit, 3PC)是在 2PC 基础上改进的一种分布式事务协议,主要目的是减少协调者单点故障导致的阻塞和脑裂风险。3PC 将提交过程分为三个阶段:
CanCommit 阶段(询问阶段)
协调者向所有参与者发送“是否可以提交”请求(canCommit)。
参与者收到后判断自己是否可以执行事务,并反馈“可以”或“不可以”。PreCommit 阶段(预提交阶段)
如果所有参与者都同意可以提交,协调者发送“预提交”请求(preCommit)。
参与者收到后执行事务操作并写入预提交日志,但还未正式提交,并反馈“已预提交”。
此时参与者可以安全地提交事务,但如果出现故障也可以回滚。DoCommit 阶段(正式提交阶段)
协调者收到所有参与者的“已预提交”反馈后,发送“正式提交”请求(doCommit)。
参与者收到后正式提交事务并释放资源。
3PC 的改进点
- 每个阶段都设置超时机制,避免无限等待。
- 预提交阶段后,参与者可以自主决定提交或回滚,减少阻塞。
- 即使协调者故障,参与者也能根据自身状态决定后续操作,降低脑裂风险。
TCC(Try-Confirm-Cancel)
角色
- 事务发起者:负责发起整个分布式事务流程,依次调用各参与者的 Try、Confirm、Cancel 接口。
- 事务参与者:实现具体的 Try、Confirm、Cancel 业务逻辑,负责资源的预留、确认和释放。
- 事务协调者(可选):用于协调和管理整个 TCC 事务的状态和流程。
主要流程
Try(尝试)阶段
检查业务操作是否可以执行,预留资源,但不做最终提交。
例如:冻结账户余额、锁定库存等。Confirm(确认)阶段
真正执行业务操作,完成资源的正式提交。
该阶段应保证幂等性(多次执行结果一致)。Cancel(取消)阶段
如果任意参与方失败或超时,执行回滚操作,释放 Try 阶段预留的资源。
该阶段也需保证幂等性。
TCC 适用于业务可以拆分为“预留-确认-取消”三步的场景,常见于金融、订单等系统。
TCC 与 2PC 的区别
- 实现层面:2PC 基于数据库,TCC 基于业务接口。
- 可用性:TCC 资源锁定时间短,支持补偿,2PC 容易阻塞。
- 幂等性与补偿:TCC 强调接口幂等和补偿,2PC 依赖数据库原子性。
- 适用场景:TCC 适合业务可拆分三步的场景,2PC 适合强一致性需求场景。
常见改进方向
- 自动补偿机制:自动重试和补偿,提升可靠性。
- 幂等性保障:Try、Confirm、Cancel 接口幂等,防止重复调用异常。
- 空回滚/悬挂处理:优化 Cancel 阶段的“空回滚”问题,通过记录事务状态避免误操作。
- 事务超时检测:增加超时检测和清理机制,防止资源长时间占用。
- 分布式事务管理器:统一管理事务状态、日志和补偿,提高可观测性和可维护性。
- 支持部分提交/柔性事务:允许部分参与者成功,失败部分通过补偿或人工介入处理,提升可用性和灵活性。
- 接口异步化:Try、Confirm、Cancel 支持异步执行,提升性能和吞吐量。
最后一个参与方提交事务的改进方案
- 异步确认:收到 Confirm 请求后先返回成功,再异步完成资源提交,提升吞吐量和响应速度。
- 批量提交:将多个 Confirm 操作合并批量处理,减少资源消耗和锁竞争。
- 幂等性保障:确保 Confirm 操作幂等,防止重复调用导致数据异常。
- 超时与补偿机制:最后一个参与方长时间未完成提交时,协调器自动检测并补偿(如重试 Confirm 或执行 Cancel)。
- 事务状态记录:本地或中心化存储事务状态,服务重启后可恢复并完成提交或补偿。
- 分布式锁优化:减少或优化资源锁定时间,避免长时间占用关键资源。
参考:实际生产环境中,分布式事务方案需结合业务需求、系统架构和性能要求综合选型和优化。