← 返回分布式系统
📏 一致性模型 · 面试深水区

一致性模型

"一致性"不是只有"强"和"弱"两档。从最强的线性一致到最弱的最终一致,中间有清晰谱系。搞清楚每个模型的"保证边界",面试才能答到点子上。

📊一致性谱系(由强到弱)

线性一致 顺序一致 因果一致 会话/单调 最终一致 越左越强(代价越高) ← → 越右越弱(越易扩展)
🧭
核心直觉:一致性越强 = 各副本表现得"像单机";越弱 = 允许短暂分歧,换更高可用与性能。没有"最好",只有"最合适"。

🎯线性一致(Linearizability)

最强的一致性。要求:每个操作都像在"全局同一时刻"原子完成,且结果对所有观察者立即可见、符合真实时间顺序。

判定标准:若操作 A 在真实时间上先于 B 完成,则所有节点都必须表现出"A 先于 B"。读一定能读到"最新一次写"。
✅
实现代价:通常需要"全局唯一序列/共识"(如 Raft 单 Leader 串行 apply)。写入要经过共识,延迟高、吞吐受限。etc/d/ZK(可配置) 接近线性一致。
🩺
典型误用:把"线性一致"和"原子性"混为一谈。原子性=事务要么全做要么不做;线性一致=跨副本的"实时可见顺序"。两者正交。

🔢顺序一致(Sequential Consistency)

比线性一致弱:所有节点看到的操作顺序一致,且每个节点的操作保持自身程序顺序,但不必符合真实时间。

与线性一致的区别:线性一致要求"按真实时间";顺序一致只要求"存在一个全局一致顺序",不要求这个顺序等于真实时间顺序。
🐘
代表:ZooKeeper 提供的就是顺序一致性——客户端写按序生效、所有客户端看到相同顺序,但不保证"写完成那一瞬间"全局立即可见。

🔗因果一致(Causal Consistency)

再弱一档:有因果关系的操作必须保序,没有因果关系的可乱序(并发)。是个很好的"性价比"模型。

A 发帖 B 评论(回复A) 因果 C 点赞(独立) D 收藏(独立) C、D 无因果→可乱序 保证:评论不会早于帖子出现;但点赞/收藏顺序无所谓
💡
适用:社交、协作编辑(如 Google Docs 的 OT/CRDT 思路)、评论系统——既保留"逻辑顺序",又允许高并发,是最终一致与强一致之间的甜点。

🌊最终一致(Eventual Consistency)

最弱:没有读写顺序保证,但只要停止写入,经过一段时间所有副本会收敛到相同值。

代表:DNS、CDN、Cassandra(可调)、Redis 主从异步复制、各类缓存。性能最高、可用性最好,但"读到旧值"是常态。
✅
何时够用:只要业务能容忍"短暂旧数据"(如商品浏览量、排行榜、头像),最终一致就是最优解。配合"读己之写"等增强,体验几乎无差。

🧭如何选型

模型代价适用典型系统
线性一致高延迟、低吞吐锁、选主、账务核心etcd/Raft、ZK(可配)
顺序一致中协调、配置ZooKeeper
因果一致中低社交、协作社交平台、CRDT
最终一致低、高扩展缓存、统计、浏览DNS/Cassandra/Redis
⚖️
经验法则:核心链路用强一致(哪怕慢点),边缘/高并发用最终一致。一个系统往往是"混合一致性"——不同数据不同等级。

🎯面试要点速记

谱系:线性 → 顺序 → 因果 → 会话/单调 → 最终,由强到弱。
线性一致:全局原子+实时可见,代价最高;靠共识实现。
顺序一致:全局顺序一致但不管真实时间;ZK 即此。
因果一致:保因果顺序,并发可乱;社交协作甜点。
最终一致:停写后收敛;性能最好;缓存/统计场景。
选型:核心强一致,边缘最终一致,混合使用。
🔥
必考题:"线性一致和最终一致的区别?"——线性一致=所有副本像单机、读写实时有序(慢但准);最终一致=允许短暂分歧、停写后收敛(快但可能读到旧值)。结合 CAP 答更完整。