分布式理论 - BASE
分布式理论 - BASE
BASE 是 Basically Available、Soft state、Eventually consistent 的首字母缩写,读作「基本可用、软状态、最终一致」。它是 CAP 定理在大规模互联网系统中的工程落地:既然分区期间必须牺牲强一致,那就主动放弃「任何时刻都一致」,转而追求「最终一定收敛」。理论侧的证明直觉见 分布式理论 - CAP。
1. BASE 从哪来
2008 年,eBay 的架构师 Dan Pritchett 在 ACM Queue 上发表《BASE: An ACID Alternative》,把 eBay 多年的大规模实践总结成一条与 ACID 相对的路线:
- ACID 追求强一致性(原子性 Atomicity、一致性 Consistency、隔离性 Isolation、持久性 Durability),是传统单机/集中式数据库的设计哲学。
- BASE 承认「瞬时一致」在大规模分布式下代价过高,于是把「一致」推迟到「最终」,用一段时间的中间态换取可用性与伸缩性。
因此 BASE 常被称作 CAP 中 AP(放弃一致性、保住可用性)路线的具体工程化:它接受了「分区期间可以不一致」,再补上一整套机制把不一致收敛回来。二者的共同前提都是:分区是常态,强一致不是免费的。
2. 三个要素
1. Basically Available(基本可用)
系统在出现不可预知故障时,允许损失部分可用性——注意是「部分」,而不是整体不可用。常见手段:
- 降级:核心链路正常,非核心功能返回兜底数据(如推荐降级为热门榜单)。
- 限流/排队:超出容量时拒绝或排队,而不是雪崩。
- 功能裁剪:关闭次要功能,把资源让给主流程。
2. Soft state(软状态)
软状态又称弱状态,与「硬状态」相对。硬状态要求任何时刻数据都是一致的;软状态允许数据在一段时间内处于中间态,即允许不同副本之间的同步存在延迟,而不认为这影响系统整体可用性。典型表现是「写入已返回成功,但某些副本尚未更新」。
3. Eventually consistent(最终一致性)
在没有新的写入的前提下,系统中的所有副本经过一段时间的同步后,最终收敛到一致状态。它不承诺「实时一致」,只承诺「终将一致」,并且要求在收敛过程中系统仍能对外提供服务。
软状态与最终一致是一体两面
「软状态」描述的是过程中的状态(允许中间态存在),「最终一致」描述的是结果上的保证(终将收敛)。二者合起来,才是完整的一条设计原则。
一个直观的例子:用户下单后,「订单创建成功」与「库存扣减」「积分增加」「发短信通知」这些动作不必在同一个事务里瞬时完成。只要订单状态、库存、积分最终都收敛到正确值,中间几秒钟的不一致是可以接受的——这就是 BASE 的思维。
需要强调的是,这种「先返回、后补偿」的顺序对用户是透明的:用户看到「下单成功」,但系统内部仍在异步地扣库存、加积分。一旦某一步失败,靠重试与补偿把它拉回一致,而不是当场把用户的请求判为失败——这正是「基本可用」与「最终一致」两支合流的交汇点。
3. BASE 与 ACID 的对比
| 维度 | ACID | BASE |
|---|---|---|
| 一致性 | 强一致,事务结束即一致 | 最终一致,允许中间态 |
| 可用性 | 常以牺牲可用性保一致 | 优先保证可用性 |
| 事务模型 | 单事务、可回滚 | 长流程、靠补偿与对账 |
| 适用场景 | 银行账务、集中式数据库 | 大规模互联网、分布式存储与电商 |
| 复杂度 | 数据库内部承担 | 补偿、幂等、对账等由应用承担 |
二者不是「谁取代谁」。真实系统往往是混用:核心账务走 ACID,周边读模型、搜索、缓存走 BASE。用一句常见的话概括:ACID 与 BASE 各自服务于不同的业务诉求,同一系统内按数据分级选用。
4. BASE 与 CAP 的关系
BASE 是 CAP 中一致性与可用性权衡的产物:由于无法在分区期间同时保住 C 和 A,大规模系统多数选择 AP,于是用 BASE 这套原则去「软化」一致性要求。更具体地说:
- CAP 给出的是取舍的边界(分区时只能二选一);
- BASE 给出的是取舍之后工程上怎么办(允许中间态,靠机制收敛)。
把一个系统硬套成「AP 还是 CP」往往过于粗糙,更实用的做法是按数据分级:库存扣减这类需要接近强一致的走 CP(如依赖共识、分布式事务),而商品计数、点赞、搜索索引这类走 BASE。更多工程取舍见 CAP 与 BASE。
5. 别把「最终一致」当躺平
「最终一致」最大的陷阱是:如果只有口号、没有配套机制,「最终」很容易变成「永远不」。要让最终一致真正成立,通常需要以下手段共同兜底:
| 机制 | 作用 |
|---|---|
| 幂等 | 重试、重复投递不产生重复扣减/重复入账;常靠唯一业务号、去重表、状态机实现 |
| 重试与退避 | 让瞬时失败(网络抖动、下游忙碌)有机会成功,配合指数退避避免雪崩 |
| 异步化(消息/事件) | 用消息队列解耦生产与消费、削峰填谷,把强耦合同步调用改造成最终一致的异步流程 |
| 补偿事务 | TCC(Try-Confirm-Cancel)、Saga 等把长事务拆成可补偿的步骤,失败时按相反方向回滚 |
| 对账任务 | 周期性扫描比对,发现不一致并告警/修复,是「最终一致」的兜底安全网 |
| 状态机 | 用明确的状态迁移描述流程,便于追踪、补偿与幂等判断 |
一个必须回答的三连问:多久能一致?如何发现不一致?发现后如何修复? 答不上来,方案就是空中楼阁。
5.1 与分布式事务方案的关系
围绕「最终一致」,业界沉淀了几套典型方案:
- 2PC / XA:两阶段提交,接近强一致,但协调者单点、阻塞、性能差,规模化系统慎用。
- TCC:业务层面的 Try-Confirm-Cancel,每个服务提供「预留/确认/取消」三个接口,靠业务补偿达到最终一致。
- Saga:把长事务拆成一串本地事务,每步都有对应的补偿动作,适合流程长、步骤多的场景。
- 本地消息表 / 事务消息:在本地事务里同时写业务数据和一条「待发送消息」,再由后台投递,保证「业务成功则消息一定发出」,是异步化落地的常用手段。
这些方案的共同点都是:放弃「一步到位」,改为「可重试 + 可补偿 + 可对账」。
6. 常见误区
- 把最终一致当成「不用管一致性」。它只是把「瞬时一致」换成「可收敛 + 可修复」,工作量不是变小而是从一个组件转移到了应用层。
- 把 BASE 当成 CAP 的替代。BASE 不是另一条定理,而是 CAP 结论之上的实现路径。
- 不分数据地全量上 BASE。账户余额、库存等本就该走强一致,硬套最终一致会带来对不上账的灾难。
- 缺少对账与告警。没有「发现不一致」的能力,最终一致就无法验证,也无法修复。
- 忽略用户感知。中间态的展示要设计好(如「处理中」「待确认」),否则用户会把正常的不一致当成 bug。
7. 小结
- BASE=基本可用 + 软状态 + 最终一致,是 CAP 中 AP 路线的工程化。
- 基本可用允许损失部分可用性(降级、限流),不是整体不可用。
- 软状态与最终一致描述「过程允许中间态」与「结果终将收敛」。
- BASE 与 ACID 是两种并存的设计哲学,应按数据分级混用,而非二选一。
- 最终一致必须配幂等、重试、补偿、对账,否则「最终」会变成「永远不」。
- TCC、Saga、本地消息表等方案,本质都是「可重试 + 可补偿 + 可对账」的落地。