引言
分布式系统是当代互联网架构的基石。从早期的单机应用到如今的云原生微服务,分布式系统的复杂性随着规模增长呈指数级上升。理解一致性模型及其工程实现,是每一位后端工程师的必修课。
CAP定理:不可能三角的哲学
2000年,Eric Brewer提出了CAP猜想,随后在2002年被Seth Gilbert和Nancy Lynch证明。CAP定理指出,在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition tolerance(分区容错性)三者不可兼得,最多只能同时满足两个。
然而,CAP定理常被误解。实际上,在网络分区(P)必然存在的情况下,系统并非在C和A之间二选一,而是在不同的一致性级别和可用性级别之间做连续谱式的权衡。
一致性模型的光谱
从强到弱,一致性模型形成了一个连续的光谱:
- 线性一致性(Linearizability):最强的一致性保证,所有操作看起来像是原子执行的,且顺序与全局时钟一致。典型实现如etcd、Consul。
- 顺序一致性(Sequential Consistency):所有进程看到的操作顺序一致,但不需要与全局时间对齐。
- 因果一致性(Causal Consistency):保证因果相关的操作在所有节点上以相同顺序被观察到。向量时钟(Vector Clock)是实现因果一致性的经典工具。
- 最终一致性(Eventual Consistency):如果没有新的更新,系统最终会收敛到一致状态。DNS系统和许多NoSQL数据库采用此模型。
共识算法:Raft与Paxos
共识算法是分布式系统的核心。Paxos作为最早的共识算法,理论优美但工程实现极其困难。Raft(2014年,Diego Ongaro)以"可理解性"为设计目标,将共识问题分解为Leader选举、日志复制和安全性三个子问题。
Raft的关键机制包括:
- Leader选举:随机超时机制避免投票分裂,保证唯一Leader
- 日志复制:Leader接收客户端请求,将日志复制到多数节点后提交
- 安全性约束:已提交的日志不可变,Leader不能覆盖已提交的条目
分布式事务的工程实践
在实际工程中,处理跨服务数据一致性的方案主要包括:
- 两阶段提交(2PC):协调者先询问所有参与者是否可以提交,全部同意后再执行提交。缺点:同步阻塞、单点故障。
- 三阶段提交(3PC):引入CanCommit阶段和超时机制,减少阻塞,但工程复杂度大增。
- TCC(Try-Confirm-Cancel):业务层面的补偿方案,Try阶段预留资源,Confirm阶段确认,Cancel阶段回滚。适用于电商下单等场景。
- Saga模式:长事务拆分为多个短事务,每个短事务有对应的补偿操作。编排式(Orchestration)和协调式(Choreography)两种风格各有优劣。
- 本地消息表:利用本地事务保证业务操作和消息写入的原子性,然后通过消息队列异步通知其他服务。
NewSQL时代的分布式一致性
Google Spanner通过TrueTime API实现了全球范围的强一致性,其核心创新是使用原子钟和GPS时钟校准,提供有界的时间不确定性。CockroachDB、TiDB等开源NewSQL数据库借鉴了Spanner的设计,在牺牲一定写延迟的前提下,提供了跨地域的串行化隔离级别。
选择一致性模型时,需回答三个问题:业务能容忍多大程度的不一致?恢复一致需要多长时间?实现强一致的代价是否可以接受?大多数场景下,最终一致性配合幂等设计已经足够,而在金融账务等核心场景,强一致性仍是必需。
分布式系统的设计没有银弹,理解权衡、根据业务特性选择合适的模型,才是工程师的核心能力。

发表评论 取消回复