「四十分钟时,面试官在白板上写了三个字母:C、A、P。让你选两个。你说AP,因为分区会发生。他们点头。然后他们问出区分资深候选人的问题:'没有分区时,延迟怎么办?'」
这是原话。不是CAP本身,是那个追问。如果你的答案是「最终一致性就行」,面试已经结束,只是你还不知道。
CAP的盲区:99%的时间在干什么
CAP起源于2000年Eric Brewer的PODC主题演讲猜想,2002年由Gilbert和Lynch证明。核心结论:分布式系统无法同时保证一致性、可用性、分区容错性。这没问题。
问题在于 framing。真实生产系统99%的生命周期里没有分区,CAP对这四九个九的正常运行时间完全沉默。
这就是PACELC要修复的。也是资深面试官真正想挖的东西。
「选两个」的表述像菜单,其实不是。分区容错在任何跨机部署的系统里都不是可选项——网络会断、包会丢、GC暂停会让集群其他节点以为你分区了。所以分区时的真实选择只在C和A之间。这部分CAP是诚实的。
但CAP没告诉你另外99%的时间发生什么。两个都标AP的数据库,正常运作时行为可能天差地别。
同一个数据库,两种完全不同的延迟
看Cassandra。健康单数据中心环,一致性级别设为ONE时,返回第一个响应的副本,通常个位数毫秒。设为ALL时,等所有副本,落到几十毫秒,任何一个慢节点都能拖长尾。
同一个数据库。同一个白板上的字母。两种完全不同的延迟与一致性权衡。
Daniel Abadi的PACELC公式给这个命了名:如果发生分区(Partition),在A和C之间选;否则(Else),在L(延迟)和C(一致性)之间选。两轴四象限:PA/EL、PA/EC、PC/EL、PC/EC。第一个字母是分区行为,第二个是稳态行为。框架就这么简单。
面试官最爱的三个:矩阵的三个角
DynamoDB(PA/EL)。分区期间可用,写被接受在有leader选举的分区任一侧。正常运作时,AWS文档写明「个位数毫秒」延迟用于最终一致读,强一致读额外收费并增加往返开销。默认就是最终一致——它选了延迟而非一致性。你可以按请求翻旗标拿强一致,付双倍读容量和明显更高延迟。权衡是暴露的。
Spanner(PC/EC)。Google围绕TrueTime构建,这个API返回小时间区间而非单点时间戳。区间内Spanner会等待(字面意义上的sleep)来保证外部一致性。正常运作时,它选了C而非L。分区时,它拒绝写直到分区恢复——选了C而非A。
CockroachDB(PC/EL)。分区时像Spanner一样选C。正常运作时用混合逻辑时钟和租约,默认提供可序列化隔离,但允许 follower 读在牺牲一致性的情况下降低延迟。你可以用AS OF SYSTEM TIME读到几秒前的快照,显式用一致性换延迟。
三个数据库。三种不同的「AP」或「CP」标签,六种不同的实际行为组合。
为什么这 matters:标签会骗人
资深面试官追问延迟,是在测试你能不能穿透标签看机制。CAP是二选一的简化,PACELC是四选二的展开。生产系统的设计空间比白板上的三个字母大得多。
下次有人问你「选CAP的哪两个」,先问:分区时还是正常时?
热门跟贴