周五傍晚,小林在群里问:“今晚吃火锅,去海底捞还是小龙坎?”阿凯秒回“海底捞!”,大壮却在地铁里信号卡顿,十分钟后才看到这条消息。从这一刻起,四个朋友的手机上出现了两种画面:阿凯的世界里已经完成了“提问—回答”,大壮的世界里提问还悬在半空。分布式系统也一样——同一份数据被复制到多个节点,由于网络延迟和故障,不同节点上看到的“世界”可能不一样。一致性模型,就是定义“这种不一样能有多大”的规则集合。 读完这篇,你会明白强一致、顺序一致、因果一致、最终一致分别对应现实中的哪类“群聊”,以及你的系统到底该选哪条规则。我们会从“四人约火锅”这个生活场景出发,把一致性模型的强度、代价、适用场景全部横着摆在一起比一比,最后落到真实的系统选型上。

岗位关联

一致性模型是分布式存储选型的地基。掌握了强弱权衡的对比框架,你才能为订单、Feed、购物车等不同业务设计出既不翻车又不浪费性能的存储方案,这是分布式系统架构师的核心能力。

目录
  1. 可视化演示
  2. 一致性模型概述
  3. 强一致性
  4. 顺序一致性
  5. 因果一致性
  6. 最终一致性
  7. 权衡对比核心
  8. 主流系统选型
  9. 实际选型决策
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示四种一致性模型强度谱系、读写可见性行为及CAP权衡三角,支持一致性强度调节。

本节配有交互动效(进入视口后自动加载,约 3KB)。

一致性强度谱系 红色线性一致性最强,实时约束全局顺序 青色最终一致性最弱,仅保证最终收敛 线性 > 顺序 > 因果 > 最终 四种模型从强到弱排列,强度与性能成反比

一致性模型概述

周末约火锅的群里,为什么同一时刻四个人看到的聊天记录不一样?因为消息是异步传播的:有人用 4G,有人连 WiFi,有人在地铁里断断续续。计算机世界更夸张,一份数据被复制到不同机房的多台机器上,每台机器之间隔着真实的物理网络,延迟和故障让它们天然“看不同步”。

如果没有额外规则,“从副本 A 读到的数据”和“从副本 B 读到的数据”可能互相矛盾。一致性模型就是约束多副本读操作可见性的规则集合,它回答三个问题:一次写成功后,什么时候能被其他节点看到?以什么顺序看到?各副本呈现的状态是否必须完全相同?我们把副本 i 在时刻 t 的状态记为 $S_i(t)$,一致性模型就是在 $S_1(t), S_2(t), \dots, S_n(t)$ 之间订立契约。

从强到弱,主流模型分为线性一致性、顺序一致性、因果一致性、最终一致性。它们对“写入何时可见、操作如何排序”逐级放宽:强一致要求全局实时对齐;顺序一致只要求存在全局合法顺序;因果一致只约束有因果关系的操作;最终一致只要求最终收敛。就像一群朋友需要约定“以谁的发言为准”,系统也需要规则来管理“多个人看到同一件事”的秩序——这决定了系统是更稳、更快,还是更扛得住故障。

强一致性

如果把一致性比作约火锅,强一致就是“开会表决”式规则:小林宣布“今晚吃海底捞”,必须等四个朋友全部回复“收到”、确认信息已在各自手机里同步,才允许任何人“知道”这个决定。不存在“阿凯知道了、大壮还不知道”的中间时刻——要么大家都没看到,要么同时看到。这种全局同时对外呈现单一视图的性质,在分布式系统里叫线性一致性,工业上通常靠 Raft/Paxos 共识协议或两阶段提交来实现。

形式化地说:任意两个操作 op₁、op₂,如果 op₁ 在实时时间上先于 op₂ 完成,那么在线性化顺序 L 中,op₁ 也必须排在 op₂ 前面。所有操作都像在某个时间点“原子地”生效,读操作永远返回最近一次写入的结果。

代价也很直接:每次写入要等全体副本确认,延迟随副本数量上升;只要一个副本失联,系统就面临阻塞或降级。多副本联合可用性约为单副本可用性的乘积,副本越多,整体越容易“约不成饭”。所以强一致最靠谱,但举手一次要等所有人到齐——正确性换来了延迟和可用性的牺牲。

op1→rtop2 ⟹ op1→Lop2\displaystyle op_1 \to_{rt} op_2 \ \Longrightarrow\ op_1 \to_L op_2
这条公式是说:一旦操作在真实时间上分出先后,所有副本看到的逻辑顺序也必须与之保持一致,不能出现“先发生的操作反而晚生效”。
  1. op₁第一个读或写操作,相当于“小林发出'去吃海底捞'的提议”。
    op1op_1
  2. →_rt实时发生顺序,即按物理时间,op₁ 完全在 op₂ 之前结束。
    →rt\to_{rt}
  3. op₂第二个操作,相当于“阿凯收到并回复收到”的后续动作。
    op2op_2
  4. ⟹蕴含符号,读作“如果……那么……”,是规则的核心逻辑连接词。
    ⟹\Longrightarrow
  5. op₁ →_L op₂在线性化顺序 L 中 op₁ 必须排在 op₂ 前,所有副本都认为 op₁ 先发生。
    op1→Lop2op_1 \to_L op_2

顺序一致性

另一种规则更像“群聊排序”:不要求大家同时看到消息,但消息必须按发送顺序到达每个人的屏幕。先有小林问“去不去?”,才有大壮答“去!”,任何人的手机上都不许出现“回答”排在“提问”之前。顺序一致性只约束顺序,不约束实时——在顺序一致的系统里,允许某些节点先执行了部分操作,其他节点暂时看到中间状态,只要最终排出的全局顺序合法即可。

形式化定义:存在一个全局操作顺序 L,任意进程 P_i 内先发的操作,在 L 中也保持同样先后。这比线性一致弱,因为不需要与真实时钟对齐——操作不必在某条“实时同步线”上同时生效。

它和线性一致的核心区别在于“时间对齐”:线性一致要求操作必须在调用和返回之间的某个真实时刻生效,读后立刻可见;顺序一致只要求存在一个合法顺序,允许短暂“穿越”。就像微信群按消息序号排序——顺序对了,晚几秒收到完全没关系,但要是“回复”显示在“提问”之前,大家就会觉得系统坏了。

∃L, ∀Pi, opa<Piopb ⟹ opa<Lopb\displaystyle \exists L,\ \forall P_i,\ op_a <_{P_i} op_b \ \Longrightarrow\ op_a <_{L} op_b
含义是:系统必须找到一个所有进程都认可的全局顺序,但不需要这个顺序与墙钟时间严格对齐,中间状态可以短暂出现。
  1. ∃L存在一个全局合法的操作顺序,每条消息在顺序里占据一个位置。
    ∃L\exists L
  2. ∀P_i对任意一个进程(朋友),这条规则都生效。
    ∀Pi\forall P_i
  3. op_a <_{P_i} op_b在进程 P_i 自己看来,op_a 先于 op_b 发生。
    opa<Piopbop_a <_{P_i} op_b
  4. ⟹蕴含,进程内先发先至,全局也不许颠倒。
    ⟹\Longrightarrow
  5. op_a <_L op_b在全局顺序 L 中 op_a 同样排在 op_b 前面。
    opa<Lopbop_a <_{L} op_b

因果一致性

现实中大多数消息根本不需要全局排序。群聊里“小林问去不去”和“阿凯说去海底捞”有因果关系——后者是对前者的回答,颠倒顺序会闹笑话。但“大壮发了个表情包”和“阿凯说海底捞”毫无关系,谁先谁后没人会注意。因果一致性只约束有因果关系的操作,无因果的并发操作允许以任意顺序出现。

在分布式系统里,用 happened-before 关系(记作 $\to$)表达因果依赖:如果 op_a 可能影响 op_b,则所有副本必须先应用 op_a 再应用 op_b。实现上通常用向量时钟(Vector Clock)追踪每个副本的因果依赖版本,确保“提问”永远不会晚于“回答”被应用。

因果一致比顺序一致更宽松,允许大量并发操作以不同顺序到达不同副本——只要不破坏因果链。购物车里“先加商品 A 再修改数量”必须保序,而“加商品 A”和“加商品 B”互不相干,乱序完全无感。这就是聊天的分寸:对话逻辑不能乱,无关的插科打诨随便穿插。

opa→opb ⟹ ∀Pi:opa 先于 opb 生效\displaystyle op_a \to op_b \ \Longrightarrow\ \forall P_i: op_a \text{ 先于 } op_b \text{ 生效}
因果一致性是“对话逻辑不乱”的数学表达:有依赖的消息必须全局按因果顺序到达,无关的消息各自飞。
  1. op_a → op_bop_a 与 op_b 之间存在因果依赖,例如“提问”先于“回答”。
    opa→opbop_a \to op_b
  2. ∀P_i对所有进程(群里的每个人)都适用,任何人的手机上都不能颠倒因果。
    ∀Pi\forall P_i
  3. 先于生效每个副本必须先应用 op_a 再应用 op_b,顺序不可逆。
    opa 先于 opb 生效op_a \text{ 先于 } op_b \text{ 生效}

最终一致性

群主在群里发“周五 7 点海底捞门口集合”,有人秒收,有人地铁里收不到,半小时后才看到。但只要最终所有人都收到这条通知,火锅照约。最终一致性就是“不承诺立刻一致,只承诺过一会儿一致”的规则:系统允许读到旧值,经过一段不可预测的时间后,所有副本最终收敛到相同状态。DNS、DynamoDB、Cassandra 都是这条路线。

它靠异步复制或后台对账实现写扩散,不需要等待所有副本确认即可返回成功。数学上,最终一致保证存在一个收敛时刻:

但“最终一致”不是“没有规则”。系统必须配套冲突处理机制:版本向量(Version Vector)检测并发写、CRDT 自动合并、或 LWW(最后写入者胜)决定谁的覆盖谁。如果每次约火锅都有人迟到半小时,聚会可能取消——最终一致的关键是“最终”是否落在业务可接受的时限内,否则强一致才是更安全的选择。

∃t0, ∀t>t0, ∀i,j: Si(t)=Sj(t)\displaystyle \exists t_0,\ \forall t > t_0,\ \forall i, j:\ S_i(t) = S_j(t)
这说明:总有某个时刻之后,任意两个副本的状态完全相等——消息迟到没关系,最终人人都有完整的那条“通知”。
  1. ∃t₀存在某个时间点,从此刻起副本们开始达成一致。
    ∃t0\exists t_0
  2. ∀t > t₀在 t₀ 之后的任意时刻,收敛保证都成立。
    ∀t>t0\forall t > t_0
  3. ∀i, j任意两个副本,相当于任意两个朋友的手机。
    ∀i,j\forall i, j
  4. S_i(t) = S_j(t)副本 i 和副本 j 在 t 时刻状态完全相同——大家都看到“周五 7 点海底捞”。
    Si(t)=Sj(t)S_i(t) = S_j(t)

权衡对比核心

假设朋友们分处两节地铁车厢,突然有人断网,群被切成两个互不相通的小圈子。这时你必须选择:暂停讨论,等断网的人上线再统一结论(一致性);还是两边各聊各的,事后同步(可用性)。你不可能同时做到“同步讨论”又“不同步交流”。这就是 CAP 定理的核心:当网络分区发生时,一致性与可用性无法同时满足,P 是分布式系统的常态而非异常,所以设计决策本质是“分区时保 C 还是保 A”。

除了可用性,延迟也是关键维度。强一致的写延迟大约等于一次网络往返乘以副本链长度,最终一致只需主副本一次本地确认。再看可用性指标:单个副本可用性为 A 时,n 个副本全部同时可用的概率是:

这个权衡就是“约火锅断网时等不等”的理论版:等,结论最准但可能永远约不成;不等,先吃上但后来的人可能不认账。没有绝对的对错,只有针对业务的选择。

分区发生时:C+A≤1\displaystyle \text{分区发生时:} C + A \le 1
如果单副本可用性 99.9%,三副本联合可用性约 99.7%——看起来差距不大,但对全年 SLA 的冲击可能直接影响赔偿条款。
  1. A单个副本的可用性,例如 99.9%。
    AA
  2. n副本数量,例如 3 个副本。
    nn
  3. A^n所有副本同时可用的概率,副本越多,整体可用性越低——因为只要有一个副本挂掉,强一致写就可能被阻塞。
    AnA^n

主流系统选型

不同群聊工具选择了不同规则:工作群要求“已读必达”、消息严格不乱序,接近强一致;闲聊群里消息偶尔乱序没人投诉,最终一致足够。分布式系统和数据库也一样,它们的模型选择直接反映了服务的业务属性。

| 系统 | 一致性取向 | 理由 |

| --- | --- | --- |

| ZooKeeper / etcd | 线性一致(Raft/ZAB) | 分布式锁、配置变更必须全局唯一 |

| DynamoDB / Cassandra | 最终一致(可配置) | 海量流量下优先保证可用性 |

| MySQL 主从复制 | 最终一致 + 读己之写 | 多数业务读多写少,容忍短暂延迟 |

| MongoDB | 可配置(主从默认最终一致,可开 majority 读) | 兼顾性能与可调强度 |

| Spanner | 外部一致(TrueTime) | 跨地域金融级数据需要全局时钟 |

为什么 ZooKeeper 必须强一致?因为“分布式锁”的场景中,两个客户端不能同时认为自己拿到了锁——这是共识问题,错了就出事故。而 DynamoDB 面对的是购物车、会话这类高并发数据,短暂读到旧值用户无感,服务不可用才是真正的灾难。MySQL 主从则走中间路线:主库写、从库读,利用半同步复制和路由策略在性能与一致性之间找平衡。

选系统之前先想清楚:你的“群友”最在乎什么?是怕消息错乱(强一致),还是怕群聊卡死(可用性),还是怕每句话都排得严丝合缝却没有性能(顺序一致的代价)?

实际选型决策

手术室的远程会诊系统不容许数据迟疑一秒,朋友圈点个赞晚三分钟显示没人记得。一致性选型,本质是回答一个问题:“如果我的数据出现短暂的旧视图,业务会不会出人命、会不会丢钱、会不会掉用户。”评估顺序像一个漏斗:先看业务容忍度,再看 SLA 延迟与可用性指标,然后估算实现成本,最后用评分模型量化比较。

最终落地的组合通常有规律:支付、库存、分布式锁选线性一致;IM 聊天、评论回复选因果或顺序一致;Feed 流、点赞计数、日志收集选最终一致。常见的坑有两个:一是无脑强一致,把金融级的成本背到所有业务上;二是选了最终一致却不配冲突处理机制,数据冲突后无人裁决。最好的一致性不是最强的,而是最匹配业务的——就像最合适的群聊规则,是让所有人舒服地吃上那顿火锅的规则。

Score=wc⋅C+wa⋅A+wl⋅L\displaystyle Score = w_c \cdot C + w_a \cdot A + w_l \cdot L
这是一个决策打分框架:给一致性收益、可用性收益、延迟损失分别配权重,算出一个综合分来对比候选方案。
  1. w_c一致性需求的权重,订单支付这类系统会给很高分数。
    wcw_c
  2. C一致性收益打分,衡量“读到旧数据”带来的业务损失程度。
    CC
  3. w_a可用性权重,面向公网、流量波动的互联网服务通常给高分。
    waw_a
  4. L延迟损失打分,每次写操作需要的跨节点往返越多,扣分越多。
    LL

AI 应用场景

秒杀系统的库存扣减(强一致)

阶段:数据写入与事务处理

解决的问题:双十一秒杀中,超卖导致订单失败、用户投诉。传统方案依赖中心化数据库锁,吞吐成为瓶颈。用强一致模型保证“扣减库存”这个操作在所有副本上原子生效,每个用户请求要么成功扣减、要么明确失败,绝不出现两个用户同时买到最后一件商品。

具体案例:电商订单系统接入 ZooKeeper 协调的分布式锁服务,商品库存写入走共识协议,所有副本确认后才返回“扣减成功”。配合限流和队列削峰,1000 万库存的商品在峰值也能保证不超卖。

朋友圈动态与点赞计数(最终一致)

阶段:异步数据复制

解决的问题:高并发下同步复制会拖垮存储,而点赞数、评论数晚几秒看到对用户无感。用最终一致模型,写入本地副本立即返回,后台异步复制到各地机房,偶尔“秒赞延迟显示”不会影响体验。

具体案例:社交平台把用户动态表按地域分片,每条动态写主分片后异步同步到读分片,通过版本号合并冲突。用户发布的动态经过短暂延迟后在全网可见,监控系统保证 99.9% 的动态在 5 秒内完成收敛。

电商购物车操作排序(因果一致)

阶段:状态与操作排序

解决的问题:用户在购物车先加入商品 A 再修改 A 的数量,两步操作有因果依赖——如果修改数量先于加购生效,旧状态会覆盖新状态,购物车数据错乱。不同商品的操作没有因果关系,乱序执行完全无感。

具体案例:购物车服务按商品维度维护版本号,每次加购生成新版本,修改数量必须携带前一个版本号才能生效;不同商品的操作并发执行,互不阻塞。用户在弱网环境下加购、改量、删除连续操作,购物车始终保持正确。

Python 演示

python84 行
import time  class Replica:    """模拟一个带版本号的数据副本"""     def __init__(self, name):        self.name = name        self.version = 0        self.data = {}     def write(self, key, value, version):        self.data[key] = value        self.version = version     def read(self, key):        return self.data.get(key)  class StrongStore:    """强一致存储:所有副本同步写入成功后,调用方才能收到确认"""     def __init__(self, replicas):        self.replicas = replicas     def write(self, key, value):        version = self.replicas[0].version + 1        for r in self.replicas:     # 全量同步,一个副本失败整体失败            r.write(key, value, version)        return version     def read(self, key):        return self.replicas[0].read(key)  class EventualStore:    """最终一致存储:主副本确认即可,后台异步同步"""     def __init__(self, replicas):        self.replicas = replicas        self.pending = []     def write(self, key, value):        version = self.replicas[0].version + 1        self.replicas[0].write(key, value, version)        self.pending.append((key, value, version))        return version     def read(self, key, idx):        return self.replicas[idx].read(key)     def sync(self):        for key, value, version in self.pending:            for r in self.replicas:                if r.version < version:                    r.write(key, value, version)        self.pending.clear()  def main():    r1, r2, r3 = Replica("上海"), Replica("北京"), Replica("深圳")     strong = StrongStore([r1, r2, r3])    strong.write("stock", 100)    print("强一致写入完成")    print("上海副本:", strong.read("stock"))    print("北京副本:", strong.read("stock"))    print("深圳副本:", strong.read("stock"))     r1, r2, r3 = Replica("上海"), Replica("北京"), Replica("深圳")    final = EventualStore([r1, r2, r3])    final.write("stock", 500)    print("\n最终一致写入完成(仅主副本确认)")    print("上海副本:", final.read("stock", 0))    print("北京副本:", final.read("stock", 1))    time.sleep(0.1)    final.sync()    print("后台同步完成后")    print("北京副本:", final.read("stock", 1))    print("深圳副本:", final.read("stock", 2))  if __name__ == "__main__":    main()
目的:用一个三副本模拟器直观演示强一致与最终一致在“写入后立刻读取”时的行为差异。
  1. r.write(key, value, version)每个副本都记录同一版本的数据,版本号用来判断新旧。
  2. for r in self.replicas:强一致必须同步所有副本,一个也不许落下。
  3. version = self.replicas[0].version + 1每次写入版本号递增,保证后写覆盖先写。
  4. self.pending.append((key, value, version))最终一致先把写入动作记入待同步队列。
  5. if r.version < version:只同步比当前副本更新的版本,避免旧数据覆盖新数据。
  6. if __name__ == "__main__":独立运行时才执行演示,方便被其他模块导入。

常见误区

误区分布式系统嘛,当然选最强的一致性,越一致越安全,其他模型都是偷工减料。约火锅一定要等所有人都确认收到消息,谁迟到都不行。

正解强一致的代价是可用性下降和延迟升高。如果约火锅必须等所有人到齐才宣布结果,有人一直断网,这顿火锅就永远约不成。CAP 定理决定了强一致与高可用难两全,互联网业务普遍优先保证可用性,只在数据库、库存、支付等关键路径上启用强一致。选型应当看业务容忍度,而不是追求“最强”。

为何常见:直觉上“更一致 = 更好”,加上教科书里线性一致的地位高,容易让人忽略它的成本。

误区最终一致不就是乱来吗?读到的数据可能是错的,系统根本没保证。群聊消息晚几分钟才到,这还能叫系统吗?

正解最终一致是一种有明确保证的模型:所有副本最终收敛到统一状态,且通常附加“读己之写”“单调读”等增强保证。群聊通知迟到但最终人人收到。设计良好的最终一致系统通过版本向量、CRDT 等机制处理冲突,丢掉写入的只会是设计者,不是模型本身。

为何常见:把“不立刻一致”误解成“永远不会一致”,忽略了收敛性这个核心承诺,也忽略了弱模型的复杂度其实藏在冲突处理里。

误区CAP 定理说一致性、可用性、分区容错三个里只能选两个,所以我选“一致性 + 可用性”就完美了,分区容错不要就行。

正解CAP 说的是网络分区发生时,C 和 A 无法同时满足;网络正常时三者可以兼得。而分区是分布式系统必须面对的现实,无法“不选”。所以真正的设计决策是“分区时保 C 还是保 A”,而不是把三个性质当静态选项任意挑选。分区容错是讨论问题的前提,不是可选项。

为何常见:教科书为了易记把 CAP 简化成“三选二”,导致很多人忽略了 P 是客观条件而非主观选择。

误区因果一致也是要求全局有序,跟顺序一致有什么区别?反正都是把操作排个序。

正解顺序一致要求所有操作存在一个全局顺序,连毫无关系的并发操作也被强行排序;因果一致只要求有因果关系的操作有序,无因果的并发操作可以以任意顺序被不同节点看到。“提问”必须早于“回答”,但“表情包”与“回答”谁先谁后无所谓。因果一致是一个偏序约束,顺序一致是一个全序约束。

为何常见:两种模型都谈“顺序”,初学者容易混淆“有序”与“全序”——一个允许并行的乱序,一个不允许。

误区MySQL 做了主从同步,读写都走主库,这不就是强一致吗?从库只是备份,不影响对外表现。

正解读写都走主库是单点写入,不是多副本强一致;一旦主库故障切换,未同步到从库的写入可能丢失,客户端视角就出现了“回滚”。即使半同步复制,也只是保证主库收到了日志,从库应用之前仍有窗口期。真正对外提供强一致需要 Paxos/Raft 共识协议或分布式事务,而不是简单主从复制。

为何常见:把“写主库”与“强一致”画等号,忽略了故障转移瞬间的观感断裂,以及从库承担读流量时的复制延迟。

面试题

Q1. 线性一致性(强一致)最核心的特征是?

单选题 · easy

  • A.所有副本同时返回结果
  • B.操作仿佛在某个时刻原子生效← 正确答案
  • C.允许读取到旧数据
  • D.只保证最终收敛

答案:B。线性一致的核心是“所有操作像在一个时间点原子生效”,读写要么都已生效、要么都未生效,不存在中间态。A 是表象不是定义;C 和 D 分别描述最终一致和弱模型。就像开会表决必须全体同时知道结果。

Q2. CAP 定理中,网络分区发生时必须在哪两者间取舍?

单选题 · mid

  • A.一致性与可用性← 正确答案
  • B.一致性与分区容错
  • C.可用性与分区容错
  • D.延迟与吞吐量

答案:A。分区是客观条件,能取舍的只有“保一致性”还是“保可用性”。约火锅时有人断网,你要么等所有人到齐(一致性),要么先吃先聊事后同步(可用性),不可能既等又不等。

Q3. 以下哪个系统采用强一致性?

单选题 · mid

  • A.ZooKeeper 配置中心← 正确答案
  • B.DynamoDB 存储服务
  • C.Cassandra 数据库
  • D.DNS 域名系统

答案:A。ZooKeeper 用 ZAB 共识协议实现线性一致,适合分布式锁和配置管理。DynamoDB、Cassandra 默认最终一致,DNS 也以缓存和最终收敛为特征。工作群才要求已读必达,闲聊群收到就行。

Q4. 因果一致性要求什么?

单选题 · mid

  • A.全部操作全局有序
  • B.因果相关操作必须有序← 正确答案
  • C.所有副本同步更新
  • D.允许消息任意乱序

答案:B。因果一致只要求存在因果依赖的操作按 happened-before 顺序生效,无因果的并发操作可乱序。“提问”必须早于“回答”,但“表情包”和“回答”谁先谁后无妨。

Q5. 下列哪些方式可以实现最终一致?

多选题 · mid

  • A.异步复制同步数据← 正确答案
  • B.定期反熵对账← 正确答案
  • C.两阶段提交强同步
  • D.版本向量处理冲突← 正确答案

答案:ABD。异步复制和对账让副本最终收敛,版本向量检测并合并并发写。两阶段提交是强一致的实现手段,与最终一致目标相反。它像“迟到但最终到齐”的群通知,需要配套设施保证到齐。

Q6. 下列说法哪个是错误的?

单选题 · easy

  • A.强一致牺牲一定可用性
  • B.最终一致只保证最终收敛
  • C.顺序一致允许部分乱序← 正确答案
  • D.因果一致只约束有关操作

答案:C。顺序一致要求所有操作存在一个全局顺序,不允许任意乱序,与实时时间是否对齐是它与线性一致的区别。A、B、D 均正确。顺序一致像群聊按序号排序,序错了系统就坏了。

Q7. 线性一致性与顺序一致性的关键区别是什么?

单选题 · hard

  • A.操作须与实时时间对齐← 正确答案
  • B.顺序一致允许丢失操作
  • C.线性一致允许因果乱序
  • D.顺序一致要求更高性能

答案:A。线性一致要求操作在真实时间窗口内原子生效,读后即知;顺序一致只要求存在合法全局顺序,允许短暂中间状态。约火锅时强一致必须所有人同时知道结果,顺序一致只要求“回复”不早于“提问”出现。

Q8. 选一致性模型时应考虑哪些因素?

多选题 · mid

  • A.业务对数据错的容忍度← 正确答案
  • B.系统的延迟与可用性 SLA← 正确答案
  • C.开发与运维实现成本← 正确答案
  • D.代码注释的数量

答案:ABC。业务容忍度决定模型强度,SLA 决定延迟和可用性约束,实现成本决定团队能否驾驭弱模型的冲突处理机制。代码注释数量与一致性模型毫无关系。

Q9. 最终一致性的“收敛”是指什么?

单选题 · easy

  • A.所有副本最终达到相同状态← 正确答案
  • B.所有请求最终失败
  • C.副本永远保持不同
  • D.只允许单副本读写

答案:A。收敛指存在某个时间点之后,所有副本的状态完全相同。群通知迟到但最终人人收到同一条消息。B、C 与收敛的定义相反,D 是单点系统不是多副本模型。

Q10. 关于 CAP 定理,正确的理解是?

多选题 · hard

  • A.无分区时可以同时满足一致性可用性← 正确答案
  • B.分区发生时算法必须取舍← 正确答案
  • C.可用性和强一致永远二选一
  • D.分区容错性可以完全回避

答案:AB。CAP 只约束分区发生时的取舍,网络正常时三者兼得;分区是常态,无法回避,只能决定优先保谁。C 夸大了约束范围,D 否定了现实的网络故障。约火锅时不是每次都断网,但断网时你必须选等还是不等。