想象你这样经营一家奶茶连锁店。单店时代,老板和店员共用一块黑板,价格永远不会分裂。但当分店开到几十家、跨越几个城市,总店每天早晨都必须打电话向每间分店广播今日价格。暴雨天,某条电话线断了——城东分店联系不上总店,顾客照样排队要买奶茶,店员盯着黑板上的旧价格心里打鼓:这个价格还作数吗? 分布式系统面对的是同一个问题:多个节点(分店)通过网络(电话)协同工作,而网络恰恰是最不可靠的部分。CAP 定理就是这场雨的天气预报,它告诉你:当电话线不可避免地断开时,你必须在“所有分店黑板价格一致”和“每个分店都能立刻营业”之间做一个艰难的取舍。一致性(Consistency)、可用性(Availability)、分区容错(Partition tolerance)——这三个概念构成了所有分布式系统设计的底层坐标。 本文将从定理的起源、三大属性的精确定义、形式化证明,讲到 CP 与 AP 在真实工程中的取舍策略,最后给出架构师的生产决策框架。读完之后,你会发现 ZooKeeper 为什么宁可拒绝请求也不给旧数据、DynamoDB 为什么愿意让你读到延迟数据——种种“怪脾气”,都能在 CAP 的框架下找到合理解释。
CAP 定理是分布式架构师的“第一性原理”。理解它,你才能真正看懂主流中间件的行为差异,在业务设计、故障排查和架构评审中做出不可替代的专业判断。
可视化演示
展示CAP三角权衡关系、网络分区下CP与AP系统行为差异及实际系统性能对比。
本节配有交互动效(进入视口后自动加载,约 3KB)。
CAP三角权衡关系 C一致性:所有节点同时看到相同数据 P分区容错:网络分区时系统继续运行 CAP只能选2/3,P不可放弃 分布式系统必须选择CP或AP
定理起源
你从一家奶茶店起步。单店时代,老板和店员面对面,黑板上的价格永远不会出分歧。后来开到十家、一百家分店,总店每天早晨要打电话给每一家分店广播今日价格。某天暴雨,一条电话线断了——总店联系不上城东分店,可城东分店还在开门营业。这就是分布式系统的出生证明:当系统从一台机器变成多台机器,“协调”本身就是最难的问题。
所有分布式系统的核心矛盾都是:多个节点通过网络协作,而网络不可靠。2000 年,Eric Brewer 在 PODC 会议上提出一个猜想:分布式系统的一致性(Consistency)、可用性(Availability)、分区容错(Partition tolerance)三者不可能同时满足。这个猜想立刻引起轰动,因为当时业界已经开始用两阶段提交(2PC)和多副本复制来解决一致性问题,但从来没有人给出过理论边界。
2002 年,Seth Gilbert 和 Nancy Lynch 发表论文,用异步通信模型严格证明了该猜想。论文的核心贡献不是提出“三选二”的口号,而是把“分区发生时系统如何应对”这个问题正式摆到了架构师面前:只要系统由多个通过网络协作的节点构成,网络分区(消息无法投递)的概率就不是零,你必须提前想好退路。
回想奶茶店,单店时代的幸福感恰恰因为不需要打电话。一旦跨城开店,“电话断线怎么办”就成了开店的必答题。CAP 定理就是给你画清楚“雨天能做什么选择”的那张地图——它不是诅咒,而是帮你把最坏情况变成可计算的选择题。
三大属性
把三个属性比作奶茶店的三个承诺。第一面招牌“黑板同步”(C):任何分店黑板上写的价格都与总店完全一致;第二面招牌“有问必答”(A):顾客任何时候进店,店员都能立刻报出价格、做好奶茶;第三面招牌“断线营业”(P):即使部分电话线断了,整个连锁体系还能按某种规则运转。
C(一致性)在 CAP 中专指线性一致性(linearizability):所有副本表现得像只有一个副本,任何一个写操作完成后,后续所有读操作都必须读到这个新值。它衡量的是“你的数据在全局时间轴上是否只有一个版本”。A(可用性)要求每个读写请求都在有限时间内收到非错误响应——注意“非错误响应”很关键,一直等待或直接抛异常都不算可用。P(分区容错)指系统在网络分区(节点间消息丢失、延迟、无法投递)时仍能继续提供服务,它不是一种可选的“功能”,而是分布式系统必须面对的环境事实。
三者关系可以这样理解:C 和 A 是业务可感知的质量指标,P 是环境硬约束。就像奶茶店,C 和 A 是顾客能直接感受到的服务质量,而电话线断不断不由你决定。在单店时代三者天然统一,一旦多店联网,C 和 A 之间就开始出现张力。
奶茶店挂出三面招牌很容易,难的是暴雨天三个承诺同时兑现——店面设计可以很漂亮,但天气不归你管。这正是接下来定理要回答的问题:当环境约束出现时,哪两个承诺还能同时守住?
定理表述
暴雨天,电话线断了,店员的处境很简单:要么告诉顾客“稍等,我打电话问总店”——但电话打不通,顾客等得不耐烦,可用性受损;要么按自己黑板上的旧价格先卖——但很可能与总店新价格不一致,一致性受损。你不可能一边“向总店确认价格”一边“立刻回答顾客”。
CAP 定理把这场雨形式化:在异步网络模型中,消息可能延迟或丢失。把系统分成两组 G₁ 和 G₂,中间网络断开。客户端向 G₁ 写入值 v,此时若 G₂ 中的读请求立刻响应,它无法获得 v(消息过不去),一致性被打破;若 G₂ 必须等 v 到达才响应,等待时间无穷,可用性被打破。这就是反证法的核心矛盾。由此得出:
定理把奶茶店的困境变成了数学:只要电话线可能断,就必须在“等总店消息”和“先按旧价格卖”之间选一条路。想清楚这个前提,后面所有工程策略都只是“选哪条路、怎么走好”的问题。
- C ∧ A同时满足一致性与可用性,即所有节点永远返回最新值,且所有请求都能及时响应。
- ⇒(蕴含)逻辑上“如果前者成立,那么后者必然成立”——这是一条硬性推导,不是经验总结。
- ¬P对分区容错的否定,等价于“网络永远不会发生分区”。
- P ⇒ (C ⊕ A)等价变形。只要分区会发生,面对分区时 C 与 A 就只能保全一个,⊕ 表示互斥二选一。
常见误解
“三选二”这句话流传太广,有人真以为 CAP 是三张牌任选两张,还有人美滋滋地选了"CA"——他们觉得只要把电话线换成光纤就不会断。可现实是:只要奶茶店开在不同城市,暴雨、施工、设备故障就会轮流来,电话线不可能永远不断。
这里需要澄清三个流行的误读。第一,P 不能被“放弃”。P 不是功能开关,而是环境事实;CA 只在“永远无分区”的理想模型中成立。真实分布式系统只要有多节点、有网络,分区概率就不是零,所以设计默认前提是 P。第二,C 与 A 不是全有全无的硬开关。权衡发生在“分区期间”这个时间窗里:无分区时两者可以同时满足;分区时可以选择拒绝部分请求保一致,也可以继续服务容忍陈旧,还可以按请求粒度混合处理。第三,CAP 不是系统级的一锤子买卖。一个大型系统内部,不同数据、不同操作可以走不同策略——核心链路用强一致,边缘功能用最终一致,用一致性级别、路由规则、超时策略组合出大量中间状态。
这些误解的共同根源,是把一个描述“极限情况”的定理当成了日常配置手册。CAP 更像交通事故安全气囊的测试标准——平时不触发,但触发时它的存在决定了乘客的生死。三张牌的说法只能帮你记住名字,不能帮你做设计。
聪明的奶茶店主不会问“我们店是纪律严明型还是灵活应变型”,而是问“哪类产品线下雨天必须保持价格统一,哪类可以事后再调”。带着这个问题,我们来看两种主流策略。
CP系统策略
“宁可错停,不可错卖”是 CP 的座右铭。城东分店电话断了,总店立刻远程把它锁死:门口挂出“暂停营业”。顾客虽然吃闭门羹,但一旦进店,黑板上的价格绝对和总店一致,没有坑。
CP 系统通过三类机制实现这个承诺。一是多数派确认(quorum):写入必须获得超过半数的副本确认才返回成功,哪怕一个副本失联,只要还剩大多数,写入仍可完成。二是选主机制:集群选举唯一 leader,所有读写都走 leader;分区后旧 leader 失联时多数派重新选主,少数派丧失服务资格。三是拒绝降级:不满足条件的请求直接返回错误或长时间等待,绝不返回可能过期的数据。ZooKeeper 的 ZAB、etcd 的 Raft、HBase、MongoDB 配置 writeConcern: majority 后,都属于这类系统。它们的共性保证是:你读到的值,一定是已经被大多数节点确认过的值。
CP 的代价是分区期间可用性下降:少数派节点拒绝读写,客户端会看到连接失败、超时或异常。所以 CP 系统必须配套客户端重试、快速失败和熔断策略。ZooKeeper 生产事故中常见的问题,就是分区时客户端在少数派节点上长时间阻塞,最终全部超时雪崩——这提醒我们,CP 不是“挂个招牌就完事”,而是需要客户端和服务端共同遵守纪律。
挂“暂停营业”的店也许会损失这半天流水,但招牌信誉保住了。对支付、库存这类业务,信誉比流水值钱——这正是 CP 系统的生存哲学。
AP系统策略
另一家奶茶店选择“先营业,后对账”:城东分店断线期间照常卖茶,按自己黑板上的旧价格成交,每笔都记在账本上。暴雨过后电话恢复,总店把新价格发过来,城东店把账本回传,差价多退少补,所有分店重新统一。顾客体验流畅,只是个别顾客可能买贵或买便宜了几毛钱。
AP 系统的核心思想是最终一致性(eventual consistency):分区期间允许每个分区独立读写,造成短暂的不一致;分区结束后通过机制自动收敛。其形式化描述是:设节点 i 和 j 存储同一份数据的副本,若分区结束后停止新的写入,它们的值会趋同:
Cassandra、DynamoDB(默认多活配置)、CouchDB 以及 Eureka(服务发现的 AP 选择)都是典型的 AP 系统。它们的代价是可能读到旧数据、并发写会产生冲突。把“先营业后对账”做成制度,靠的正是版本号和合并规则——这在工程上比 CP 的“暂停营业”更复杂,也更考验业务容忍度。
- Vi(t) 与 Vj(t)节点 i 和节点 j 在时刻 t 存储的同一数据的副本值。
- lim(极限)当时间 t 趋向无穷大时观察结果——表示“分区结束并持续同步足够久之后”。
- 差值为零两副本的值最终完全一致,差异消失,系统达到收敛状态。
工程决策
成熟奶茶店不会全店一个策略:招牌芋圆奶茶的价格全国统一、绝不偏差,这是 CP;季节限定新品允许分店推出“本地特惠”,事后对账,这是 AP。一条街上的连锁店,两类产品同时存在。
架构师做 CAP 决策时看四个维度。第一,数据性质:资金、库存、订单、实名信息错误代价高,选 CP;点赞数、浏览数、推荐位短暂偏差无感,选 AP。第二,业务容忍度:能不能接受读到旧值?支付页面余额必须准,feed 流里少一条新鲜事无妨。第三,故障影响面:核心链路(下单、扣款)用强一致 + 多副本;非核心链路(通知、统计)用最终一致 + 异步。第四,降级预案:平时走 AP 的系统在极端场景可临时切换为“CP 式拒写”以保护数据;平时走 CP 的系统也要设计“本地缓存兜底”,避免整个核心链路被拖死。
生产复盘案例:某电商大促时订单中心走 CP(MySQL 主从 + 分布式事务),购物车和优惠券展示走 AP(Redis 缓存 + 异步对账)。一次机房光纤抖动导致订单写入短暂失败,但因为熔断和重试机制,最终没有资金差错;而非核心的购物车短暂显示了旧优惠券,用户可感知但无资损。这次复盘的关键结论是:CP 保护了钱,AP 保住了体验,两者各司其职。
好的连锁店管理手册会写清楚:“哪些品类必须全国统价,哪些品类可以本地灵活。”CAP 决策的本质,就是把这条“分数线”画对。
演进方向
电话线从铜线变成光纤再变成 5G,越来越稳,但雨季和施工队永远存在。奶茶店主真正要做的不是祈祷不断线,而是把“断线时的柜台操作手册”提前写好。
CAP 定理只回答了分区发生时的取舍,却遗漏了“无分区时”的权衡。PACELC 模型补全了这块拼图:
与此同时,共识算法(Raft、ZAB、Paxos)让 CP 系统实现变得工程化,选主、日志复制、快照等细节成为可靠基础设施的标准件;多活架构让每个区域自治(AP 式)加全局同步(CP 式)混合;边缘计算在本地保留副本,减少跨区请求,降低分区对用户体验的影响。但无论技术怎样演进,只要网络物理上不可靠,权衡逻辑就不会消失。
奶茶店的管理从“老板一个人说了算”进化成“一套自动化的沟通仪式”,但雨天预案永远写在使用手册第一页。CAP 定理教你的不是选边站,而是把“哪边更重要”想清楚再站。
- P → (A vs C)分区发生时,第一优先级的决策是在可用性与一致性之间选择,这与 CAP 定理一致。
- ¬P → (L vs C)没有分区时,决策转向延迟(Latency)与一致性之间的权衡——强一致往往需要跨节点确认,延迟更高。
AI 应用场景
电商订单库存系统设计
阶段:系统架构设计 / 数据一致性保障
解决的问题:下单、扣库存、支付链路如果读到过期数据,会导致超卖和金额错误。传统做法是数据库行锁加分布式事务,所有节点等待多数派确认,写入慢但正确;若盲目追求高可用而放弃强一致,则可能造成资损。
具体案例:某交易系统在机房光纤抖动时,订单中心主动返回 503 而非乱扣款,用户重试后成功;库存服务保持 CP,避免超卖;同时优惠券展示走 AP,短暂显示旧券但不影响资损。正是“核心链路 CP、非核心链路 AP”的混合设计,让一次物理故障没有演变成资金事故。
社交信息流与点赞计数
阶段:数据写入路径设计
解决的问题:朋友圈点赞、浏览数每秒几十万次写入,要求每个请求立刻成功。传统强一致方案会因锁和多数派确认带来高延迟和请求丢失,用户体感变差。
具体案例:某内容平台用 AP 思路:点赞先写本地缓存,后台异步批量同步,最终一致;热门视频的点赞数短暂偏差可接受,但视频的上架/下架状态走 CP,保证审核结果全局生效。通过把“展示型数据”和“状态型数据”分流,既保住了体验,也保住了底线。
微服务注册中心选型
阶段:基础设施选型
解决的问题:注册中心负责服务发现,每个服务上线或下线都要通知其他服务。选 CP(etcd/ZooKeeper),分区时注册中心可能拒绝服务,但不会把“半死不活的服务”发给调用方;选 AP(Eureka),目录始终可用,但调用方可能请求到已下线的实例。
具体案例:某公司把核心交易链路的注册中心用 etcd(CP),保证路由信息绝对可靠;把非核心的配置读取用 Nacos(支持 AP 模式),保证配置中心随时可读。两条链路都通过心跳和重试机制兜底,既避免了单点,也把分区影响隔离在非核心范围。
Python 演示
"""CAP tradeoff simulator: partition scenario demo.""" class Node: def __init__(self, name, value=0, version=0): self.name = name self.value = value self.version = version self.partition = 0 def write(self, value): self.value = value self.version += 1 class KVStore: def __init__(self, node_names): self.nodes = [Node(n) for n in node_names] self.majority = len(self.nodes) // 2 + 1 def set_partition(self, partitions): for node in self.nodes: node.partition = partitions.get(node.name, 0) def reachable(self, node): return [n for n in self.nodes if n.partition == node.partition] def write_cp(self, node, value): peers = self.reachable(node) if len(peers) < self.majority: return False, "minority cannot confirm" for n in peers: n.write(value) return True, "majority confirmed" def write_ap(self, node, value): node.write(value) return True, "local write ok" def read_all(self): return {n.name: (n.value, n.version) for n in self.nodes} def main(): store = KVStore(["A", "B", "C"]) print("normal state:", store.read_all()) store.write_cp(store.nodes[0], 1) print("write 1 ok:", store.read_all()) store.set_partition({"A": 1, "B": 1, "C": 2}) ok, msg = store.write_cp(store.nodes[0], 2) print("CP write under partition:", ok, msg) ok, msg = store.write_ap(store.nodes[2], 3) print("AP write under partition:", ok, msg) print("divided state:", store.read_all()) store.set_partition({"A": 1, "B": 1, "C": 1}) ok, msg = store.write_cp(store.nodes[2], 2) print("merge catch-up write:", ok, msg) print("final state:", store.read_all()) if __name__ == "__main__": main()
self.majority = len(self.nodes) // 2 + 1计算多数派门槛,3 个节点需要 2 个确认才算写入成功。def set_partition(self, partitions)模拟网络分区,把每个节点划入不同的分区组。def reachable(self, node)找出与指定节点同分区的“可达副本”,模拟断线后只能与同区通信。if len(peers) < self.majority:CP 写入的核心检查:可达副本不足多数派就拒绝写入。for n in peers: n.write(value)CP 要求多数派内所有副本都更新后才返回成功。store.write_ap(store.nodes[2], 3)AP 模式下分区内的节点直接本地写入,不等待多数派。print("divided state:", store.read_all())展示分区期间两侧各自的值(2 和 3),不一致窗口出现。store.set_partition({"A": 1, "B": 1, "C": 1})恢复网络(分区消除),为最终收敛做准备。
常见误区
误区很多教程说 Cassandra 是最终一致的,所以它不满足 CAP 的 C;那 CAP 的 C 是不是就是“数据最终会对齐”?
正解CAP 的 C 特指线性一致性(linearizability),即读操作必须反映“某个逻辑时刻之后”最新的写结果。最终一致性是 AP 系统在分区结束后收敛的性质,讨论的是“分区结束后数据如何趋同”,两者根本不是同一个概念。一个系统完全可以在正常情况下提供强一致,在分区时降级为最终一致,不能简单用“最终一致”概括它的 C。
为何常见:最终一致性这个词传播最广,新手容易把“数据最终会一样”理解成“一致性”,忽略了 CAP 对一致性的严格定义。
误区CAP 既然是三选二,那我可以选 CA——只要网络足够稳定,没必要管分区容错,把精力都放在强一致和高可用上。
正解P 不是“功能开关”而是“环境事实”。只要系统节点分布在不同机器、不同机房,网络分区、丢包、时钟漂移就必然存在概率。CAP 的真正表述是:当分区发生时,C 和 A 只能保一个;无分区时两者可以同时满足。CA 系统只在理想的“无分区”假设下成立,在真实分布式环境里不存在。
为何常见:“三选二”这个口头禅太顺口,容易让人以为三个是平等的可选项,而忽略了 P 是分布式系统的默认前提。
误区选了 CP,系统在分区时整个服务停摆;选了 AP,系统数据永远对不上,业务没法做。
正解CP 系统分区时只是“无法保证所有副本一致的那部分写入”被拒绝,多数派一侧通常仍可正常服务;AP 系统通过版本号、时间戳、CRDT 等机制在恢复后自动收敛。两者都有大量生产实践支撑,差别是权衡窗口和恢复机制,不是“好与坏”的差别。
为何常见:把生活中的“要么全对要么全错”二元思维带进来,忽略了 CAP 讨论的是“分区期间”这个特定时间窗,而不是系统的常态表现。
误区既然 CAP 这么重要,那我可以给整个系统定一个 CP 或 AP 的策略,一劳永逸。
正解生产系统是分层混合的:订单、库存这类核心写路径选 CP;阅读数、点赞、推荐这类读多写少、可容忍延迟的走 AP。同一套架构里既有强一致的 MySQL 主从和 etcd,也有最终一致的缓存和消息队列。架构师按数据重要性和业务容忍度逐条决策,而不是给整个系统贴一个标签。
为何常见:CAP 以“系统”为单位讨论,容易让人忽略系统内部可以按数据、按接口、按故障域做细粒度拆分。
误区机房光纤很稳,一年也遇不到一次分区,主要精力应该放在性能优化上,不用为小概率事件做预案。
正解在分布式系统里,交换机升级、云厂商故障、GC 停顿造成的心跳超时都可能触发“逻辑分区”。除非系统只有单副本,否则设计必须假设分区会来,并提前定好降级预案。预案平时不触发,但一旦触发,就决定用户感知到的是一致性问题还是可用性问题。
为何常见:单点、小规模系统很少遇到分区,经验局限让人低估了分区的发生概率——它往往不是“线路断了”,而是各种隐性原因导致的“消息不通”。
面试题
Q1. CAP 定理中的"P"(分区容错)本质是指什么?
- A.系统能容忍部分节点宕机
- B.网络消息丢失或节点失联← 正确答案
- C.数据可以在机房间迁移备份
- D.系统能自动恢复被删除的数据
答案:B。P 指网络分区,即节点间的消息会丢失、延迟或无法到达。宕机只是可能触发分区的一种原因,迁移备份、数据恢复都不是 P 的定义。就像奶茶店电话线断了,核心问题是“消息传不过去”。
Q2. 关于“三选二”的正确理解是?
- A.三个属性可以任选两种来设计
- B.分区时 C 和 A 只能保全一个← 正确答案
- C.无分区时也必须放弃一种
- D.分区容错在实际中总能避免
答案:B。CAP 定理说分布式系统中 P 是必须面对的现实,分区发生时 C 与 A 不可兼得;无分区时两者可同时满足。“三选二”是简化说法,不是自由任选——你不能选"CA"然后指望网络永远不断。
Q3. ZooKeeper 在发生网络分区时的行为属于?
- A.保证可用性牺牲部分一致性
- B.保证一致性拒绝非多数派请求← 正确答案
- C.同时保持强一致和高可用访问
- D.自动切换到灾备机房继续服务
答案:B。ZooKeeper 是典型 CP 系统:分区后少数派节点不再接受读写,多数派集群继续服务,保证线性一致性。它宁可让少数派“暂停营业”,也不让顾客看到错误价格。
Q4. AP 系统的数据“最终一致”通常依赖什么实现?
- A.事务提交后全局加分布式锁
- B.版本号与冲突合并机制来收敛← 正确答案
- C.所有写入必须获得多数派确认
- D.客户端本地缓存全部数据副本
答案:B。AP 系统不强求多数派确认,用版本号、时间戳、CRDT 等在恢复后合并冲突、收敛一致。A 和 C 是 CP 的典型手段;D 与 AP 无关。就像奶茶店恢复电话后靠账本对账,而不是断线时锁死柜台。
Q5. 以下属于 CP 策略的机制有?
- A.写入需多数派副本确认← 正确答案
- B.分区时少数派拒绝服务← 正确答案
- C.冲突双方各自保留旧版本
- D.心跳选举产生唯一主节点← 正确答案
答案:ABD。A、B、D 是 CP 的典型机制:多数派确认、拒绝降级、选主。C 是 AP 策略——保留冲突版本等待合并。CP 的目标是“宁可等,也不给错价”。
Q6. 下列哪个系统通常被认为采用 AP 策略?
- A.ZooKeeper 使用 ZAB 协议选主
- B.MySQL 主从同步保证强一致性
- C.DynamoDB 默认多区域最终一致← 正确答案
- D.etcd 写入需 Raft 多数派确认
答案:C。ZooKeeper、MySQL 同步复制、etcd 都是 CP 系或强一致配置;DynamoDB 默认多活、允许最终一致,是典型 AP。AP 系统追求“先营业后对账”。
Q7. 生产系统常进行 CP/AP 混合设计,合理做法有?
- A.订单扣库存走强一致的 CP 链路← 正确答案
- B.点赞计数走异步最终一致更新← 正确答案
- C.所有读写必须由单一中心节点处理
- D.核心链路降级时启动缓存兜底← 正确答案
答案:ABD。混合设计按数据重要性分流:核心强一致、边缘最终一致、故障降级兜底。C 把所有流量集中到单一中心节点,与分布式设计的初衷相悖,也不属于混合策略。
Q8. 下列关于 PACELC 扩展模型的描述,正确的是?
- A.分区时只考虑可用性这一个指标
- B.无分区时权衡延迟和一致性即可← 正确答案
- C.该模型完全取代了 CAP 定理本身
- D.平时权衡点位于可用性和分区容错
答案:B。PACELC 补充了 CAP 没覆盖的“无分区”场景:分区时(P)选 A 或 C,否则(Else)在延迟(L)与一致性(C)间权衡。它是 CAP 的扩展而非取代,平时权衡的是延迟和一致性,不是可用性和分区容错。
Q9. 网络分区发生时,AP 系统可能出现的现象有?
- A.两侧同时写入互相冲突的数据← 正确答案
- B.读到尚未同步的过期旧数据← 正确答案
- C.分区结束后执行冲突合并收敛← 正确答案
- D.少数派副本拒绝处理任何读取
答案:ABC。AP 允许两侧继续服务,代价是短暂不一致、冲突和读到旧数据,恢复后收敛。D 是 CP 行为——拒绝少数派读取。AP 对应的是“先营业,后对账”。
Q10. CAP 定理的证明中,核心矛盾发生在什么场景?
- A.节点宕机后从备份中恢复数据
- B.分区时两侧同时响应同一次请求← 正确答案
- C.请求在正常网络中被延迟处理时
- D.客户端并发发起大量重复的请求
答案:B。证明把系统分成两组,假设中间网络断开。若两侧都能及时响应同一个写请求,则任一侧可能读到旧值,破坏一致性;若必须等对方确认,等待时间无限,破坏可用性。正是“同时响应”这个要求让 C 和 A 不可兼得。