1. 一个具体问题

两个机房都保存库存,网络突然中断。甲机房已经卖出最后一件商品,乙机房无法知道这个事实,却收到新的购买请求。让乙继续成功出售,会破坏库存的统一视图;让它等待或拒绝,就无法保证这个请求继续获得正常处理。

2. 一句话解释

在可能发生网络分区的分布式系统中,不能同时无条件保证线性一致性和每个非故障节点对请求的可用性。

3. 出处与原意

Eric Brewer 在 2000 年提出相关猜想,Seth Gilbert 与 Nancy Lynch 于 2002 年在形式化模型中给出证明。这里的一致性主要对应原子读写或线性一致性,可用性有严格的终止要求,不等同于运营报表中的“可用率达到几个九”。

4. 原理与机制

关键不在字母三选二,而在节点失去通信时无法区分“另一边没有更新”与“另一边已经更新但消息未到”。若必须给出符合全局最新状态的结果,就可能等待通信恢复或限制一侧操作;若每侧都要持续完成请求,就可能出现无法纳入单一实时顺序的结果。定理没有说所有操作都必须采用相同策略,也没有直接讨论吞吐量、事务隔离级别和一般延迟。分区恢复后的冲突合并更是额外设计任务。

“返回错误”不能简单算作定理要求的可用性,否则任何系统都可以立即报错来同时宣称满足全部保证。另一方面,实际产品可以把拒绝写入设计为清楚且可恢复的体验。多数派协议也不是分区中每一侧都停止:哪些请求能继续取决于节点划分、领导者与数据位置。讨论时必须具体到操作语义,避免把集群整体贴标签后忽略细节。

5. 一个完整案例

假设案例:两个仓库共售一个限量商品,剩余库存为一。系统选择由多数派确认扣减,网络把节点分成三台和两台时,只有三台一侧可以完成需要共识的写入,两台一侧提示暂时不可购买。与此同时,商品介绍仍可从本地缓存读取,即使内容稍旧也能接受。团队把“购买成功”的含义定义为库存已获确认,并为失败保留重试提示。这个设计牺牲的是部分请求在分区时的可用性,而不是整个网站永久不可用。

6. 适用条件与反例

适合讨论跨节点共享状态在通信故障下的承诺。单机数据库的设计不能靠贴一个 CA 标签解释完整风险,读取缓存也不能在没有定义一致性语义前随意称为 AP。实际还要分析超时、客户端行为、数据丢失窗口和恢复流程。

7. 今天可以尝试的行动

挑一个重要写操作,写出网络隔离时两边各自会返回什么、哪些成功承诺绝不能反悔、恢复后如何校验冲突。用一次故障演练验证这些语义,再讨论数据库标签;对用户有意义的是请求结果,而不是三个字母的组合。

8. 参考资料与关联条目

关联条目:PACELC 模型;端到端原则。