一致性级别对比矩阵
学完了线性一致性、顺序一致性、因果一致性、最终一致性,以及介于最终一致性和强一致性之间的单调保证,现在来做一次横向对比。
分布式系统的一致性不是一个二元问题,而是一个从强到弱的光谱。理解这个光谱的全貌,才能在系统设计时做出明智的权衡。
一致性光谱总览
每一级都比上一级更弱,但也更容易实现、性能更高。
完整对比表
各维度详细说明
全局顺序:所有操作是否必须有一个统一的全局顺序?
- 严格一致性/线性一致性/顺序一致性:必须
- 因果一致性:必须有,但只针对有因果关系的操作
- 单调保证/最终一致性:不必须
实时序:是否要求「先完成」的操作排在「后开始」的操作前面?
- 严格一致性/线性一致性:必须
- 顺序一致性/因果一致性/单调保证/最终一致性:不必须
因果保证:是否保证「如果 A 导致 B,则 A 必须排在 B 前面」?
- 强一致性(严格/线性/顺序):是(因为它们更强)
- 因果一致性:是(这是它的核心保证)
- 单调读/读你所写:部分(只保证会话内的因果)
- 最终一致性:否
延迟与一致性权衡
一致性和延迟的关系可以这样理解:
这个关系不是绝对的,但大致成立。原因在于:
- 强一致性需要协调:跨节点同步、共识协议、心跳保活,这些都会增加延迟
- 弱一致性允许本地操作:写操作可以立即返回,读操作可以从本地副本返回
量化对比
以下数据来自公开基准测试和论文(仅供参考,实际数值因场景而异):
延迟的差异主要来自「是否需要跨节点协调」。线性一致性通常需要多数派确认(N/2+1 节点),最终一致性只需要写入本地节点。所以最终一致性的延迟可以比线性一致性低一个数量级。
选型决策树
面对具体的业务场景,如何选择合适的一致性级别?
决策要点详解
问题 1:业务能接受短暂不一致吗?
如果不能(如金融交易、库存扣减),跳过剩余问题,直接考虑强一致性方案。
如果能(如社交动态、配置缓存),继续问题 2。
问题 2:需要分布式锁或 Leader 选举吗?
如果是,必须选择线性一致性。因为分布式锁依赖实时序。
如果否,继续问题 3。
问题 3:需要全局顺序吗?
如果是(如消息队列的分区顺序),选择顺序一致性。
如果否,继续问题 4。
问题 4:需要因果保证吗?
如果是(如协作编辑、评论排序),选择因果一致性。
如果否,继续问题 5。
问题 5:需要单调保证吗?
如果是(如展示用户状态、购物车),选择单调读/读你所写。
如果否,选择最终一致性。
场景选型表
CAP 定理再理解
CAP 定理指出:在分区(Partition)发生时,必须在一致性(Consistency)和可用性(Availability)之间权衡。
但 CAP 定理常被误解。关键在于:CAP 不是三选二,而是「分区时二选一」。
重要澄清:CAP 的 C 是指「线性一致性或等价的一致性」,不是「最终一致性」。
- CP 系统:etcd、ZooKeeper、HBase(分区时可能不可用)
- AP 系统:DynamoDB、Cassandra、Riak(分区时永远可用,但可能返回旧数据)
现实中的混合模式
现代分布式系统通常不只使用一种一致性级别,而是在不同模块使用不同级别:
DynamoDB 的例子
DynamoDB 提供了多种一致性模式:
Cassandra 的例子
Cassandra 默认是最终一致性,但可以通过配置开启更强的保证:
面试总结
如果你是面试官,问到分布式一致性相关的问题,通常期望你掌握以下几点:
1. CAP 定理的准确理解
CAP 不是三选二。分区时,必须在一致性和可用性之间选择。没有分区时,两者都可以保证。
2. 一致性光谱的完整图景
从强到弱:严格一致性 > 线性一致性 > 顺序一致性 > 因果一致性 > 最终一致性。每个级别的核心保证是什么,它们之间的关系是什么。
3. 选型的权衡思维
不是「越强越好」,而是「根据业务需求选择最合适的」。金融系统需要线性一致性,社交媒体可以接受最终一致性,协作工具需要因果一致性。
4. 典型系统的对应关系
- etcd / ZooKeeper:线性一致性
- DynamoDB / Cassandra:最终一致性(可配置)
- SequalDB:顺序一致性
5. 实现代价的理解
强一致性需要共识协议、跨节点协调,这会带来延迟。理解为什么因果一致性比线性一致性快,最终一致性比因果一致性快。
思考题
问题 1:如果一个系统声称「同时满足 CAP 三角的三个方面」,这是可能的吗?
参考答案
不可能。在分布式系统中,分区(网络故障)是必然发生的。当分区发生时,CAP 三角的 P 是必然的,必须在 C 和 A 之间选择。
但有一种特殊情况:单机系统。单机系统不存在网络分区,所以可以同时满足 C 和 A。但这不是分布式系统的讨论范畴。
问题 2:DynamoDB 默认是最终一致性,但它是如何在「不需要用户处理冲突」的场景下工作的?
参考答案
DynamoDB 使用了多种策略:
-
设计层面避免冲突:DynamoDB 的数据模型(KV/文档)天然冲突少,不像关系数据库那样有复杂的事务依赖。
-
冲突处理策略:DynamoDB 默认使用「最后写入胜出」(LWW),对于购物车等场景使用语义合并。
-
应用层可选:DynamoDB 也支持「返回所有冲突版本」让应用层处理,这需要开发者承担更多责任。
关键点是:DynamoDB 把「什么时候让用户处理冲突」这个决策权交给了开发者,而不是系统。
问题 3:因果一致性比线性一致性「弱」,但为什么说它仍然是一种「强一致性」?
参考答案
「强一致性」和「弱一致性」的划分是相对的:
- 相对于最终一致性,因果一致性是「强」的,因为它保证了有意义的顺序
- 相对于线性一致性,因果一致性是「弱」的,因为它不要求实时序
所以「强一致性」通常指的是「比最终一致性更强的所有级别」,包括线性一致性、顺序一致性、因果一致性。
因果一致性被称为「强一致性」是因为它保证的核心东西——「有因果关系的操作有序」——对于大多数业务场景来说已经足够了,而且比线性一致性更容易实现。
术语表
延伸阅读
如果你对一致性模型还想深入,可以继续探索:
- 悲观 vs 乐观并发控制:一致性模型是「悲观」的(假设冲突一定会发生),而乐观锁是「乐观」的(假设冲突很少发生)
- 柔性事务(BASE):与 ACID 事务相对,BASE 强调基本可用、软状态、最终一致
- CRDT(无冲突复制数据类型):一种可以在最终一致性系统下实现强语义的特殊数据结构
一致性是分布式系统中最核心的话题之一。希望这个系列文章能帮助你建立起完整的知识体系,在未来的系统设计中做出明智的权衡。