想象一个遍布全国的连锁咖啡品牌:总部和几十家分店的收银系统通过网络彼此相连,共享同一份菜单、价格和库存数据。平时一切顺畅,但只要某个分店与总部之间的通信线路被台风刮断,这家分店就成了“孤岛”——它还能继续卖咖啡吗?卖出的价格会不会和总部不一致?这些问题的答案,正是分布式系统中著名的 CAP 定理和 PACELC 扩展。 CAP 定理告诉我们:网络分区(断连)无法避免,一旦发生,你只能在“一致性”(所有分店价格相同)和“可用性”(顾客随时买得到咖啡)之间选一个。而 PACELC 扩展进一步补充:哪怕没有台风,平时你也要在“响应速度”和“数据一致”之间做权衡。这篇文章就跟着这家连锁咖啡店开分店的历程,把这两个理论彻底讲透,并落到真实互联网系统的工程选型上。

岗位关联

理解 CAP 与 PACELC 是分布式系统设计的第一性原理。AI 从业者无论是搭建大模型训练集群、部署推理服务,还是设计 AI 平台的多租户任务调度,都必须用这套取舍框架做架构决策——它直接决定系统的可用性与数据可靠性。

目录
  1. 可视化演示
  2. 核心概念
  3. 不可能三角
  4. PACELC扩展
  5. 一致性谱系
  6. 系统选型
  7. 工程实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

拖拽滑块观察CAP三选二取舍,对比CP与AP系统在分区下的行为,并理解PACELC在无分区时的延迟-一致性权衡。

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

CAP三选二 分区时在C与A中选择 P不可省略 PACELC扩展无分区权衡

核心概念

连锁咖啡店开业前,老板必须先想清楚几个基础问题:总店和分店之间怎么联网?菜单和价格数据放在哪里?顾客进店买咖啡时怎么响应?这些问题映射到分布式系统,就是四个基础概念:分布式系统、数据一致性、可用性和网络分区。

分布式系统由多台独立运行的计算机(节点)组成,它们通过网络传递消息、协作完成同一业务。在咖啡店的比喻里,总部和各家分店的收银机都是独立节点:每个节点有自己的 CPU、内存和存储,谁也不能直接读取别人的内存,只能靠网络通信交换信息。

一致性(Consistency)指所有节点在同一时刻持有的数据视图完全一致。咖啡店要求“全部门店价格同步”——A 分店改了菜单,B 分店的收银机也必须立刻显示新价格。用形式化语言描述“全局一致”:任意两个节点的数据值在任何时刻都相等:

C:∀i,j∈Nodes,Vi=Vj\displaystyle C: \forall i, j \in Nodes, \quad V_i = V_j

1. 节点集合 Nodes:系统中全部节点(分店)的集合,公式要在所有这些节点上做全称量化。

Nodes={node1,node2,…,noden}Nodes = \{ node_1, node_2, \ldots, node_n \}

2. 全称量化 ∀i, j:意思是“任意”两个节点都必须满足约束,不允许任何一对节点例外。

∀i,j∈Nodes\forall i, j \in Nodes

3. 视图相等 V_i = V_j:节点 i 看到的数据视图 V_i 与节点 j 的 V_j 完全相同,这一个等号是极强的约束。

Vi=VjV_i = V_j

可用性(Availability):系统对每个请求都必须在有限时间内给出非错误响应。顾客在任何分店都能立刻买到咖啡,不能因为“数据还没同步完”就拒绝服务。网络分区(Partition)则是节点之间通信链路中断、消息无法送达——现实中分区不是“会不会发生”的问题,而是“什么时候发生”的问题。对咖啡店而言,这就是台风刮断了两家分店之间的电话线。

不可能三角

台风真的来了。总部到 B 分店的线路中断,两边彻底失联。B 分店的收银机里存着昨天的价格,而总部刚刚调了价。顾客照样进店买咖啡,B 分店必须二选一:要么按旧价格卖(保住可用性,但数据不一致);要么挂出“暂停营业”(保证一致性,但伤害可用性)。两个都要?不可能——因为你既无法确认总部新价格,也无法把自己的价格同步给总部。

CAP 定理(Eric Brewer 2000 年提出,后被形式化证明)说的正是这件事:一个分布式系统,不可能同时满足一致性(C)、可用性(A)和分区容忍性(P),最多同时满足两个。为什么“三个都要”不可能?当分区把节点分成 G1、G2 两组,G1 收到写请求后,要保持可用性,G1 必须返回成功;要保持一致性,G2 必须与 G1 数据相同——但 G2 根本收不到同步消息。所以:系统可用则两组数据必然不同(违背 C);系统一致则 G2 必须拒绝响应(违背 A):

P⇒(C∧¬A)∨(A∧¬C)\displaystyle P \Rightarrow (C \land \lnot A) \lor (A \land \lnot C)

1. 分区发生 P:系统被划分成两组互不可达的节点 G1 与 G2,这是前提,也是物理世界无法避免的事实。

P:G1↔G2 不可达P: G_1 \leftrightarrow G_2 \ \text{不可达}

2. 保持一致性 C:若选一致性,G2 在无法确认最新数据前不能返回响应,只能挂起或拒绝,于是失去可用性。

C⇒¬AC \Rightarrow \lnot A

3. 保持可用性 A:若选可用性,G2 必须立即响应,但本地数据是旧的,读取结果与新写入冲突,于是失去一致性。

A⇒¬CA \Rightarrow \lnot C

关键在于:P 不是你可以取舍的选项,而是必须接受的现实约束。所以 CAP 实际只告诉你一句话——分区发生时,你是要和旧数据共存(AP),还是和临时停机共存(CP)。咖啡店老板的选择同理:B 分店“先按旧价卖、事后补差价”就是 AP;“挂上暂停营业的牌子”就是 CP。

PACELC扩展

台风总会过去,但老板陷入新的困惑:风和日丽的时候,难道就没有权衡了吗?CAP 定理只描述了“分区时”的困境,对“没有分区时”系统该如何取舍只字未提。PACELC 扩展(Daniel Abadi 于 2012 年提出)恰好补上了这块拼图。

PACELC 的完整表述是:如果分区发生(P),那么在可用性(A)和一致性(C)之间二选一;否则(Else,记为 E)——也就是系统正常运行时——在低延迟(Latency, L)和一致性(C)之间二选一。为什么“平时”也有权衡?为了做到强一致,每次写操作都必须同步复制到所有副本,等全部确认才给客户端返回“成功”,延迟自然变高;如果采用异步复制,写操作发给一个节点就立刻返回,速度快了,但读请求可能读不到刚写的数据。L 与 C 就这样形成跷跷板:

PACELC: (P⇒A⊕C)∧(E⇒L⊕C)\displaystyle \text{PACELC: } (P \Rightarrow A \oplus C) \land (E \Rightarrow L \oplus C)

1. 异或符 A ⊕ C:分区时,可用性与一致性互斥,只能且必须选择其一。

P⇒A⊕CP \Rightarrow A \oplus C

2. 常态 E(Else):E 表示不存在分区的正常运行状态,这是 PACELC 相对 CAP 新增的讨论区间。

E=¬PE = \lnot P

3. 延迟与一致 L ⊕ C:正常情况下,低延迟与强一致相互竞争,选低延迟则牺牲强一致,选强一致则增加延迟。

E⇒L⊕CE \Rightarrow L \oplus C

咖啡店平时也要做这道选择题:总部每次调价,如果坚持“所有分店确认收到新价格后才对外发布”(选 C),顾客要等很久;如果“先发布、各店陆续同步”(选 L),顾客立刻买到咖啡,但存在短暂的价格不一致窗口。对卖奶茶(社交动态)可以选 L,对卖金条(金融账务)必须选 C。

一致性谱系

“一致性”并不是非黑即白的开关,而是一条从强到弱的光谱。咖啡店总部的公告,有的是“立即生效”(强一致),有的是“本周内各分店陆续执行”(最终一致)。理解这条光谱,你才能把 PACELC 中“选 C”精确到具体强度。

从强到弱,常见的一致性模型包括:强一致性(任何读操作都能读到最近一次写的结果,所有分店收银机同步更新,绝无例外);顺序一致性(所有节点上的操作顺序一致,但不要求与真实时间完全对应);因果一致性(有因果关系的操作按序可见,无因果的操作可以乱序);最终一致性(没有新写入后,经过一段收敛时间,所有副本最终达到相同状态——分布式系统中最广泛使用的“实用一致性”)。最终一致性的形式化定义是:存在一个时间点 t₀,在它之后任意两个副本的数据视图永远相同:

∃t0,  ∀t>t0,  ∀i,j:Vi(t)=Vj(t)\displaystyle \exists t_0, \; \forall t > t_0, \; \forall i, j: \quad V_i(t) = V_j(t)

1. 存在时间点 t₀:收敛发生的时刻,t₀ 越小代表收敛越快,这是“最终”的时间度量。

∃t0\exists t_0

2. 所有更晚时刻 ∀t > t₀:从 t₀ 之后的任意时刻,性质都必须成立,不允许再出现分叉。

∀t>t0\forall t > t_0

3. 双副本一致 V_i(t) = V_j(t):任意两个副本在任一时刻的数据视图相同,这份承诺就是“最终”二字的分量。

Vi(t)=Vj(t)V_i(t) = V_j(t)

从读写视角还能拆出几种实用保证:读己之写(自己刚写的内容马上能读到)、单调读(不会读到比之前更旧的数据)、写后读(写操作完成后,后续读都能看到)。咖啡店的做法是:B 分店可以先按旧价卖,但必须保证“顾客刚才付的价格,在小票上不会变”——这就是读己之写。

系统选型

知道了光谱和权衡,店长就要给不同的“店面”定策略了。真实世界的分布式系统,几乎都在 CAP/PACELC 框架下做了明确选型。

CP 系系统:ZooKeeper、etcd、HBase 等,任何情况下优先保证一致性,分区时宁可拒绝服务。典型场景是分布式锁、配置中心、元数据存储——这些数据一旦不一致,整个系统都会错乱,所以“不可用几分钟”远比“数据错乱”容易接受。AP 系系统:Cassandra、DynamoDB、CouchDB 等,优先保证可用性,用最终一致性和冲突解决机制兜底。典型场景是购物车、社交信息流、点赞计数——短暂不一致的代价远小于一次请求失败。

Quorum 机制提供了一种灵活折中:Amazon Dynamo 用“读多少副本、写多少副本”的参数来调节一致性强度。设副本总数为 N,写需 W 个副本确认,读需读取 R 个副本,只要满足下面不等式,读写集合必有重叠,读操作就一定能读到最新写入的数据:

W+R>N\displaystyle W + R > N

1. 副本总数 N:一份数据在多少台机器上各存一份,N 越大容错越强,但同步开销也越大。

N=3(例如三副本)N = 3 \quad (\text{例如三副本})

2. 写确认数 W:写操作要等多少个副本确认成功才向客户端返回成功,W 越大写越慢、越安全。

1≤W≤N1 \le W \le N

3. 读副本数 R:读操作要读取多少个副本后取最新版本返回,R 越大读越慢、越不容易读到旧数据。

1≤R≤N1 \le R \le N

4. 交集条件 W+R>N:读写副本集合必然重叠,重叠的那个副本一定包含最新写入版本。

W+R>N  ⟺  读写集合有交集W + R > N \iff \text{读写集合有交集}

通过调参可以做到“按需一致”:W=3、R=1 是写慢读快的强一致;W=1、R=1 是读写都快但弱一致;W=2、R=2 是折中。对咖啡店而言,这相当于把“总部确认价格的分店数”和“顾客能看到的价格来源数”以可调的方式匹配起来。

工程实践

理论最终要落到工程。有经验的店长不会等台风来了才做决定,而是提前写好应急预案。分布式系统的工程实践同样围绕“事前分片、事中降级、事后对账”三条主线展开。

架构取舍:微服务架构中,不同服务可以采用不同策略——订单服务走 CP 保证账实相符,推荐服务走 AP 允许特征短暂过期。评价架构不是看“用了哪个模型”,而是看“每个子模块是否选对了适合自己业务的模型”。降级策略:分区发生时快速识别核心与非核心链路,核心链路(如支付)切 CP 保证数据正确,非核心链路(如个性化推荐、日志采集)降级或采用最终一致。数据分片:通过分片(Sharding)把数据按业务维度切分,任何一次分区只影响一个分片,把爆炸半径控制到最小(就像把门店分成几个大区,各有独立备货中心)。

监控与对账:最终一致的系统必须配套对账补偿机制——定期扫描副本差异,用版本号、校验和或操作日志修复不一致数据,同时对同步延迟、分区次数、可用性指标持续监控。可用性的数学定义是正常服务时间占总时间的比例:

A=Ttotal−DdownTtotal\displaystyle A = \frac{T_{total} - D_{down}}{T_{total}}

1. 总时间 T_total:评估周期内的总时长,通常取一年(365 天)。

Ttotal=365×24×60×60 秒T_{total} = 365 \times 24 \times 60 \times 60 \, \text{秒}

2. 停机时间 D_down:周期内系统无法提供正常服务的累计时间,包括分区导致的拒绝服务。

Ddown=∑ΔtdownD_{down} = \sum \Delta t_{down}

3. 可用性比率 A:可用时间占比,业界常说的“几个 9”就是 A 的十进制表示。

A=99.9%  ⟺  年停机 8.76 小时A = 99.9\% \iff \text{年停机 } 8.76 \text{ 小时}

把 CAP/PACELC 内化为条件反射:每次设计一个分布式模块,先问三个问题——这里能容忍分区吗?分区时选 C 还是 A?正常时选 L 还是 C?想清楚这三问,架构就成功了一大半。

AI 应用场景

大模型训练集群的元数据管理

阶段:分布式训练基础设施(任务编排与状态管理)

解决的问题:千卡训练集群产生海量元数据——模型版本、超参数、检查点(checkpoint)文件索引、节点心跳。传统方案把信息散落在各节点本地文件,节点宕机后信息丢失,训练无法恢复,甚至出现“两个节点用不同版本模型继续训练”的灾难。用 etcd(CP)存放任务元数据与主节点选举信息,保证所有训练节点对“谁是主节点、当前用哪个版本”认知一致;日志与监控指标则写入 AP 系统,允许短暂延迟。

具体案例:某公司训练千亿参数大模型时每 5 分钟保存一次检查点,元数据写入 etcd。某个参数服务器宕机后,新节点从一致的元数据中快速恢复正确的权重分片位置,训练中断从小时级降到分钟级。

推荐系统特征服务的一致性取舍

阶段:在线推理前的实时特征处理

解决的问题:实时推荐要把用户最新点击、收藏合入特征向量。若每次特征更新都等全部分片同步完成,推荐接口延迟会从 50ms 涨到 300ms 以上,直接拖垮体验。采用 PACELC 的“平时选 L”策略——特征副本异步更新,牺牲短暂一致换取低延迟;同时保证“读己之写”,让用户自己的行为立即生效。分区时切 AP 并用版本号合并冲突。

具体案例:某短视频平台特征服务在晚高峰每秒处理百万级行为事件,特征库异步复制将 P99 延迟稳定在 80ms 以内;偶发分区时短暂返回旧特征,用户无感知,但“自己刚点赞的内容尽快出现在自己的推荐里”通过读己之写得到保证。

多租户 AI 平台的任务调度

阶段:AI 平台 PaaS 层的作业调度与资源分配

解决的问题:调度器必须避免“双主”导致的资源竞争。传统单点调度器挂掉后任务状态全部丢失。采用 CP 的 etcd 做分布式选主,保证任意时刻只有一个主调度器持有租约;各 Worker 的任务状态上报走 AP 消息队列,允许重复上报,由主调度器幂等合并。调度决策强一致,状态采集最终一致。

具体案例:某云厂商 AI 训练平台用 etcd 管理调度器租约,主调度器故障后 30 秒内完成选主切换,运行中的训练任务不受影响;节点状态通过消息队列最终一致地汇总到控制面,避免状态风暴打垮数据库。

Python 演示

python81 行
class Node:    """一个副本节点, 持有价格数据"""     def __init__(self, name, price):        self.name = name        self.price = price  class CapSimulator:    """双节点系统, 模拟分区下的 CP 与 AP 行为差异"""     def __init__(self):        self.n1 = Node("node1", 30)        self.n2 = Node("node2", 30)        self.partition = False        self.mode = "CP"        self.pending_sync = None     def set_partition(self, on):        self.partition = on     def set_mode(self, mode):        self.mode = mode     def write(self, node_name, new_price):        node = self.n1 if node_name == "node1" else self.n2        # CP 模式: 隔离节点拒绝写入, 保一致性        if self.partition and node is self.n2 and self.mode == "CP":            return "REJECT: CP mode halts writes for isolated node"        node.price = new_price        if not self.partition:            # 无分区: 双节点同步写            self.n1.price = new_price            self.n2.price = new_price            return "OK: synced to both nodes"        # AP 模式: 本地写入, 记录待同步        self.pending_sync = (node_name, new_price)        return "OK: accepted locally, sync deferred"     def read(self, node_name):        node = self.n1 if node_name == "node1" else self.n2        if self.partition and node is self.n2 and self.mode == "CP":            return "REJECT: CP mode refuses reads for isolated node"        return node.price     def heal(self):        """分区恢复: 把待同步的写入补发到所有节点"""        self.partition = False        if self.pending_sync:            _, price = self.pending_sync            self.n1.price = price            self.n2.price = price            self.pending_sync = None            return "HEALED: pending write synced"        return "HEALED: no pending write"  def run_demo():    sim = CapSimulator()    print("== normal phase ==")    print(sim.write("node1", 35))    print("node1:", sim.read("node1"), "| node2:", sim.read("node2"))     sim.set_partition(True)    sim.set_mode("CP")    print("\n== partition + CP mode ==")    print("write node2:", sim.write("node2", 40))    print("read node2:", sim.read("node2"))     sim.set_mode("AP")    print("\n== partition + AP mode ==")    print("write node2:", sim.write("node2", 40))    print("node1:", sim.read("node1"), "| node2:", sim.read("node2"))     print("\n== partition heals ==")    print(sim.heal())    print("node1:", sim.read("node1"), "| node2:", sim.read("node2"))  if __name__ == "__main__":    run_demo()
目的:用两个节点模拟“总部与孤岛分店”,直观对比分区发生时 CP 模式(拒绝服务)与 AP 模式(本地写入、延迟同步)的行为差异。
  1. if self.partition and node is self.n2 and self.mode == "CP":判断“分区中 + 隔离节点 + CP 模式”三个条件同时成立
  2. node.price = new_price只把新价格写入本地,模拟分店收银机独立记账
  3. self.pending_sync = (node_name, new_price)AP 模式下记录待同步写入,等分区恢复后补发
  4. def heal(self):分区恢复时的“对账补偿”:把延迟的同步补发给所有节点
  5. sim.set_partition(True)模拟台风刮断线路(网络分区)
  6. sim.set_mode("AP")店长切换策略:从“关门保一致”切到“营业但价格可能过时”

常见误区

误区我一直以为 CAP 定理就是“三个特性里随便选两个”,所以我们可以为了极致的一致性和可用性,干脆不要分区容忍性。反正我的系统又不出故障。

正解分区容忍性 P 不是选项而是前提。分布式系统的节点跨机房、跨网络部署,断电、光缆被挖断、交换机故障都会造成节点失联,分区是物理世界的必然事件。CAP 的真实含义是:P 必选,只能在 C 与 A 之间二选一。就像咖啡店老板不能决定“台风不来”,只能决定台风来临时门店怎么办——是关门还是按旧价营业。

为何常见:“三选二”的简化表述太流行,初学者误以为三个角可以任意舍弃;再加上单机或实验环境里分区极少发生,更强化了“P 可以不要”的错觉。

误区我觉得 CAP 只在网络断连的极端情况才需要考虑,平时系统风平浪静,一致性和可用性都能同时满足,根本不需要做选择。

正解平时确实能同时满足 C 和 A,但代价是“慢”——每次写都要同步等待所有副本确认。如果你既想要强一致又想要低延迟,二者会互相打架。PACELC 正是把这种“平时”的权衡显式化:E 场景下要在 L 与 C 之间选择。咖啡店平时也要决定“调价是否等全部门店确认后再发布”。

为何常见:CAP 定理只讨论分区场景,容易让人误以为“没有分区就没有权衡”。这个盲区由 PACELC 补上,但很多学习者只学了 CAP 就停了。

误区既然数据“最终”才一致,那和没有一致性约束有什么区别?反正迟早会乱,干脆当成弱一致性不管了。

正解最终一致性承诺“停止写入后所有副本最终收敛到完全相同”,还附带读己之写、单调读等可兑现的保证。它和“没有约束”有本质区别:一个是有明确收敛目标的异步同步,一个是毫无章法。DynamoDB、Cassandra 正是靠它在超大规模下保持可用。咖啡店“先按旧价卖、恢复后统一补差价”也是一种有明确终点的处理。

为何常见:把“最终”误解为“随意”,忽略了定义中的存在时间点 t₀ 和确定性的收敛承诺。

误区我们用了 Raft 共识算法做多副本同步,是不是就能绕过 CAP 定理,同时保证一致性和可用性?

正解共识算法(Raft/Paxos)解决的是“无分区时如何高效达成一致”和“分区恢复后如何快速收敛”,它能大幅缩短不可用窗口,但无法消除 CAP 的本质矛盾。分区期间多数派与少数派依然无法通信:少数派若继续服务,数据必然与多数派不一致(牺牲 C);若暂停服务,则牺牲 A。共识算法是“止痛药”,不是“万能药”。

为何常见:看多了“Raft 保证强一致”的宣传,容易相信技术能战胜物理约束;忽略了共识算法本身也有“多数派存活”这一可用性前提。

面试题

Q1. CAP 定理中,当网络分区发生时,系统真正面临的选择是?

单选题 · easy

  • A.一致性 vs 可用性二选一← 正确答案
  • B.分区容忍性 vs 一致性二选一
  • C.分区容忍性 vs 可用性二选一
  • D.三个特性全部可以兼得

答案:A。分区(P)是分布式系统的必然约束,必须被容忍,所以真正的取舍是分区时在一致性 C 与可用性 A 之间二选一。B、C 都把 P 当作可舍弃项,D 直接违背定理。就像台风天,分店只能选择“关门保价格一致”或“营业但价格可能过时”。

Q2. 以下哪个是典型的 CP 分布式系统?

单选题 · easy

  • A.Cassandra
  • B.DynamoDB
  • C.ZooKeeper← 正确答案
  • D.CouchDB

答案:C。ZooKeeper 用于分布式锁和配置中心,分区时宁可拒绝服务也不返回不一致数据,是 CP 系统。Cassandra、DynamoDB、CouchDB 都是 AP 风格——优先保证可用性,用最终一致性兜底。好比“金库”型店面:关门可以,账不能错。

Q3. PACELC 模型中的字母 E 代表什么?

单选题 · easy

  • A.Eventual 最终一致性
  • B.Else 表示无分区平时← 正确答案
  • C.Encryption 数据加密
  • D.Extreme 极端场景

答案:B。PACELC 中 P=分区、A=可用性、C=一致性、E=Else(无分区)、L=延迟。E 特指“没有分区时的正常状态”,PACELC 正是在这个场景补充了“延迟与一致性”的权衡,补上了 CAP 定理的盲区。

Q4. 某系统分区时拒绝写请求以保证数据一致,平时写操作则要求所有副本确认后才返回。它的策略是?

单选题 · mid

  • A.分区选 C,平时选 C← 正确答案
  • B.分区选 A,平时选 L
  • C.分区选 C,平时选 L
  • D.分区选 A,平时选 C

答案:A。分区时拒绝写 = 保证一致性舍弃可用性,对应 P 场景选 C;平时等所有副本确认 = 牺牲延迟换取一致,对应 E 场景选 C。合起来是 CP/EC 策略,是元数据存储类系统的典型选择。

Q5. 副本数 N=3 时,下列哪组 Quorum 参数无法保证读到最新写入?

单选题 · mid

  • A.W=2,R=2
  • B.W=3,R=1
  • C.W=1,R=1← 正确答案
  • D.W=1,R=3

答案:C。Quorum 保证强一致的条件是 W+R>N。N=3 时,A 组 2+2=4>3、B 组 3+1=4>3、D 组 1+3=4>3 都成立;只有 C 组 1+1=2≤3,读写副本集合可能没有交集,读请求可能读不到最新写入。就像顾客恰好走进一家还没收到调价通知的分店。

Q6. 下列关于最终一致性的描述,正确的是?

单选题 · mid

  • A.系统永远不保证数据正确
  • B.停止写入后副本最终收敛一致← 正确答案
  • C.写操作必须等所有副本确认
  • D.读操作总是会立即返回最新值

答案:B。最终一致性承诺“停止写入后经过一段收敛时间,所有副本最终到达相同状态”——存在 t₀ 之后任意两副本视图相等。A 是误解;C 描述的是强一致的写策略;D 说“立即返回最新值”违背了最终一致的定义。

Q7. 下列关于 PACELC 模型的说法,正确的有?

多选题 · hard

  • A.它只在分区发生时起作用
  • B.无分区时也要权衡延迟与一致← 正确答案
  • C.它是对 CAP 定理的补充扩展← 正确答案
  • D.它表明分区可以完全避免

答案:BC。PACELC 的增量贡献在于把 CAP 没讨论的“无分区常态”纳入框架:即使网络畅通,也要在低延迟 L 与一致性 C 之间权衡,它是对 CAP 的补充而非替代。A 错在它同时也覆盖常态场景;D 错在它承认分区无法避免。

Q8. 以下业务场景中,适合选择 AP 风格系统的是?

多选题 · mid

  • A.朋友圈动态点赞统计← 正确答案
  • B.分布式锁获取
  • C.商品浏览计数← 正确答案
  • D.银行账户余额扣减

答案:AC。点赞统计和浏览计数属于高并发、可容忍短暂不一致的业务,选 AP 可保证任何时刻都能响应。分布式锁和银行余额是强一致场景,必须选 CP。好比奶茶店可以先卖、事后对账;金库不行。

Q9. 关于 CAP 定理,下列说法正确的有?

多选题 · hard

  • A.网络分区是分布式系统必然面对的现实← 正确答案
  • B.分区时一致性与可用性不可兼得← 正确答案
  • C.无分区时系统可以同时满足 C 与 A← 正确答案
  • D.引入共识算法即可同时获得 C 与 A

答案:ABC。A、B 是 CAP 定理的核心结论;C 也正确——无分区时节点通信畅通,可以同时满足 C 和 A,但要付出同步延迟的代价,这正是 PACELC 讨论的 E 场景。D 错误:共识算法只是缩短不可用窗口,分区时多数派与少数派依然无法既一致又可用。

Q10. 某系统分区时优先保证可用性并用版本合并收敛,平时采用异步复制降低延迟。它对应 PACELC 哪种策略?

单选题 · extreme

  • A.CP/EC
  • B.CP/LC
  • C.AP/EL← 正确答案
  • D.AP/EC

答案:C。分区时“保证可用性并靠版本合并收敛”= 选 A;平时“异步复制降低延迟”= 选 L。因此对应 AP/EL,这正是 DynamoDB 类系统的典型设计。CP/EC(如 etcd)分区时拒绝服务、平时同步复制;CP/LC 分区时不一致性优先,与题意相反。