{T}

不同数据一致性模型有哪些应用?

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:消息不能"先看到的反而是后发的"(同一条会话线程内);
  • 分布式数据库:yugabyteDBMongoDB 的因果一致性会话(causal consistency sessions)。

4. 业务如何选择

选型决策树:

text
业务能否容忍读到旧值?
├─ 完全不能(钱、锁、选主、配置) → 线性/顺序一致性(etcd、ZooKeeper、强同步复制)
├─ 短窗口可以(订单状态、库存超卖可控) → 半同步复制 / 1 主多从 + 路由策略
└─ 长时间可以(Feed、点赞、统计) → 最终一致(异步复制 + 对账补偿)

工程实践要点:

  1. 同一系统的不同数据可以不同模型:订单主数据走强一致,商品快照走最终一致;
  2. 一致性模型可以叠加:MySQL 半同步 + 读写分离路由"主库读关键数据";
  3. 衡量指标:不一致窗口(staleness window)、收敛时间(convergence time)、读旧值概率。

5. 小结

  • 一致性模型是从"最强"到"最弱"的光谱:线性 > 顺序 > 因果 > 会话 > 最终;
  • 线性一致性(etcd/ZooKeeper)用于锁、选主、配置等错误代价高的场景;
  • 最终一致性(异步复制、DynamoDB)用于可容忍短时陈旧的高并发读场景;
  • 因果一致性是中间地带的最优解:保证因果不错乱,允许并发乱序
  • 选型不是"全系统一刀切",而是按数据维度决定一致性强度。

下一章讲解共识算法鼻祖 —— Paxos:两阶段提交协议、多数派机制与活锁问题。