不同数据一致性模型有哪些应用?
0. 引言
一致性模型定义了"读写操作在全系统面前呈现什么顺序"的约定。CAP 告诉我们必须在 C 与 A 之间取舍,一致性模型则给出了"折中到什么程度"的精确刻度:从最强(线性一致性)到最弱(最终一致性),每档都有对应的典型系统与适用业务。本文按强度从高到低梳理各模型,并落到具体组件的工程实现上。
1. 一致性模型谱系
图表渲染中…
越往左越强,代价是更低可用性、更高延迟;越往右越好用,代价是需要业务容忍窗口期不一致。
2. 各模型定义与对比
| 模型 | 核心约束 | 读到的数据 | 典型系统 |
|---|---|---|---|
| 线性一致性 | 所有操作等价于按真实时间顺序原子执行,读必读到最新写 | 永远最新 | ZooKeeper 同步读、etcd、etcd 分布式锁 |
| 顺序一致性 | 所有节点看到同一顺序,但顺序不必匹配真实时间 | 一致但可能"迟到" | 分布式事务提交顺序、Raft 日志应用 |
| 因果一致性 | 有因果依赖的操作按因果序被看到;并发操作可乱序 | 因果正确即可 | 评论回复、IM、CRDT 部分实现 |
| 会话一致性 | 同一会话内读写一致(读己之写);跨会话不保证 | 自己写的一定读得到 | 购物车、登录态、Web 会话 |
| 最终一致性 | 无新写入时,副本最终收敛到相同值;收敛时间无上限 | 可能旧值 | DNS、CDN 缓存、MySQL 异步复制、Cassandra |
线性一致性 vs 顺序一致性:线性一致性 = 顺序一致性 + 顺序必须与真实时间一致(写操作完成的那一刻起,所有后续读都必须看到它)。Raft 的日志顺序保证的是顺序一致性,而 etcd 的线性化读(
--consistency=linearizable)额外通过 ReadIndex/Lease 机制对齐真实时间。
3. 工程中的落地形态
3.1 强一致的代表:ZooKeeper / etcd
- ZooKeeper:写操作由 Leader 串行执行(ZAB 广播),
sync读 + 顺序一致性保证;8.0 版本(3.9+)支持follower 读时通过followerSync保证顺序。 - etcd:Raft + ReadIndex 提供线性一致性读;KV 接口、Lease、Watch 是 Kubernetes 控制面一致性的基石。
- 适用:分布式锁、选主、配置下发、服务注册——这些场景"读到旧值"的代价是致命的(双主、重复发放)。
3.2 最终一致的代表:异步复制与去中心化存储
- MySQL 主从异步复制:主库提交即返回,从库延迟窗口内读到旧数据;半同步复制(
semi-sync)通过等待一个从库 ack 缩小窗口,组复制(MGR)则更接近强一致。 - Cassandra / DynamoDB:默认
QUORUM读写可在线性一致与最终一致之间调参(ONE/QUORUM/ALL)。 - 适用:读多写少、对短时陈旧不敏感的场景(商品详情、Feed 流、计数)。
3.3 折中派:因果一致性的价值
因果一致性是"性价比最高"的模型:它允许并发操作乱序,但保证有因果关系的操作不乱序。典型需求:
- 评论系统:回复必须在原评论之后出现;
- IM:消息不能"先看到的反而是后发的"(同一条会话线程内);
- 分布式数据库:
yugabyteDB、MongoDB的因果一致性会话(causal consistency sessions)。
4. 业务如何选择
选型决策树:
text
业务能否容忍读到旧值?
├─ 完全不能(钱、锁、选主、配置) → 线性/顺序一致性(etcd、ZooKeeper、强同步复制)
├─ 短窗口可以(订单状态、库存超卖可控) → 半同步复制 / 1 主多从 + 路由策略
└─ 长时间可以(Feed、点赞、统计) → 最终一致(异步复制 + 对账补偿)工程实践要点:
- 同一系统的不同数据可以不同模型:订单主数据走强一致,商品快照走最终一致;
- 一致性模型可以叠加:MySQL 半同步 + 读写分离路由"主库读关键数据";
- 衡量指标:不一致窗口(staleness window)、收敛时间(convergence time)、读旧值概率。
5. 小结
- 一致性模型是从"最强"到"最弱"的光谱:线性 > 顺序 > 因果 > 会话 > 最终;
- 线性一致性(etcd/ZooKeeper)用于锁、选主、配置等错误代价高的场景;
- 最终一致性(异步复制、DynamoDB)用于可容忍短时陈旧的高并发读场景;
- 因果一致性是中间地带的最优解:保证因果不错乱,允许并发乱序;
- 选型不是"全系统一刀切",而是按数据维度决定一致性强度。
下一章讲解共识算法鼻祖 —— Paxos:两阶段提交协议、多数派机制与活锁问题。