公司动态

一致性模型:不一条线走到黑

📅 2026/9/3 5:28:37
一致性模型:不一条线走到黑
复制把数据放到多台机器每台只持有部分的真相。这就带来一个不可避免的问题同一份数据有多个副本读的时候到底能看到哪个版本一致性模型就是对这个问题的回答——系统给外部一个什么样的承诺关于「读到什么」。为什么需要一致性模型数据分散到多节点后写操作不会瞬间同步到所有副本。在同步完成的那个窗口里不同节点看到的数据可能不一样。这不是 bug是物理规律——消息传输需要时间。但应用不能接受随便读到什么。你转账成功之后查余额必须看到新数字。你发了一条评论刷新页面得看到自己的评论。这些需求能不能满足取决于系统选择什么一致性模型。一致性模型就是一份合约。系统说我按这个规则保证你读到的数据。你按这个规则用。规则越强保证越好代价越大。规则越弱代价越小但你要自己处理更多边缘情况。线性一致性最强的承诺。系统对外表现得像只有一个副本——任何操作看起来都在某个瞬间完成所有客户端看到的操作顺序一致。线性一致性就是「我刚写了你就能读到」。一个写操作完成后后续所有读操作必须返回新值不管读的是哪个副本。实现这个承诺需要共识协议——比如 Raft 或 Paxos——确保多数节点确认后才返回。像 ATM 取款机。你取了钱余额立刻变后面排队的人插卡看到的绝对是新余额。没人会看到「扣了钱但余额没变」——系统表现得像只有一台机器在管这笔账。etcd 是典型。它用 Raft 保证线性一致性所有写操作都经过 leader 确认。代价是延迟——写要等多数节点确认才能返回。如果网络抖动共识协议会让操作变慢。但换回来的是你不会读到旧数据不会出现「写成功了但读不到」的现象。MySQL 的主从复制不是线性一致的。主库写完从库还没追上你读到从库看到的是旧数据。这就是主从的代价——复制延迟打破了线性一致性。顺序一致性比线性弱一档。不要求操作按实时顺序——只要求所有操作看起来按某个全局顺序执行并且每个客户端自己的操作顺序保持。像体育比赛回放。裁判按时间顺序判了三次犯规这个顺序所有观众都同意。但不同人看到判罚的「实时时间」可以差几秒——直播有延迟有人看得快有人看得慢。每个观众自己看到的顺序是一致的但不同观众之间谁先看到不保证。Zookeeper 提供的是顺序一致性。所有写操作按顺序应用到所有节点客户端自己的操作保持先后但不同客户端之间的实时顺序不严格保证。Zookeeper 用 ZAB 协议类似 Raft确保所有节点按同一顺序应用操作。因果一致性再弱一档。只保证有因果关系的操作按顺序看到。A 写了数据B 读到后写了评论——这两个有因果关系顺序不能乱。但 C 和 D 同时各自写了一条不相关的数据——没有因果关系不同客户端可以按不同顺序看到。像微信朋友圈。你发了照片朋友评论了——谁先看到照片谁后看到评论这个顺序不会乱因为有因果关系评论依赖照片。但两个朋友各自发了一条朋友圈没有因果关系不同人刷到的顺序可以不一样。你看到的是 A 先 B 后别人看到的是 B 先 A 后都不算错。向量时钟能实现因果一致性。DynamoDB 和 Riak 都走这条路——用向量时钟检测哪些写之间有因果关系只对有关系的保证顺序没关系的接受并发。MongoDB 的因果一致性 session 也是这个思路。在同一个 session 里写后读保证看到自己的写但不同 session 的操作顺序不保证。最终一致性最弱的承诺。不保证什么时候一致只保证「如果不再有新写过一阵子所有副本会一致」。像图书馆还书。你还了一本书系统里不会立刻显示可借——分拣、上架、更新目录要时间。过一阵子你再搜能借了。中间这段时间不同人搜到不同结果有的人搜到已归还有的人还搜到在借。但最终都会一致——书确实在架上。DNS 是最终一致性的经典案例。你改了一条 DNS 记录有的 DNS 服务器立刻生效有的缓存要等几小时。中间这段时间不同用户解析到不同的 IP。这是「最终」——不是立刻但总会一致。最终一致性不弱——它是分布式系统最普遍的运行状态。主从复制从节点滞后时系统就是最终一致的。多主复制的跨数据中心同步也是最终一致的。无主复制的读修复和反熵还在跑时还是最终一致的。不是开关是刻度一致性不是二选一。不是「要么强一致要么最终一致」。是一排刻度——线性、顺序、因果、最终——从左到右越来越弱越来越便宜。CAP 定理说得更直白网络分区发生时强一致和可用性二选一。选强一致线性——分区期间部分节点不可用。选高可用——接受最终一致性等分区恢复再同步。实际系统很少只选一档。etcd 是线性一致性但它的读可以走 follower线性读要额外确认。Kafka 的消息消费是顺序一致性的思路——同一个分区内保证顺序跨分区不保证。Cassandra 的 quorum 是可调的——你可以按需要调一致性级别。选哪档取决于你的应用能不能接受「读到旧数据」。转账不能用户昵称可以广告展示无所谓。想清楚你的数据容忍什么再选什么。小结一致性模型是分布式系统对外的承诺。线性一致性最强——像 ATM取完钱余额立刻变但要共识协议撑。顺序一致性放松了跨客户端实时约束——像比赛回放各自看到的顺序一致但谁先看到不保证。因果一致性保因果关系不保并发排序——像朋友圈你发的和评论你的不会乱别人发的无所谓顺序。最终一致性是兜底——像图书馆还书上架过一阵子总会一致。这一排不是谁对谁错是代价。强一致延迟高弱一致应用要处理更多边缘。选了哪档就是选了「用延迟换正确性」还是「用正确性换延迟」。