每一个分布式系统的开发者都不可避免的要去接触和了解CAP定理。

2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想。2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP。之后,CAP理论正式成为分布式计算领域的公认定理。

CAP理论概述

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

CAP最初是作为一个经验法则提出的,没有准确的定义,目的是开始讨论数据库的权衡。那时候许多分布式数据库侧重于在共享存储的集群上提供线性一致性的语义,CAP定理鼓励数据库工程师向分布式无共享系统的设计领域深入探索,这类架构更适合实现大规模的网络服务。 
对于这种文化上的转变,CAP值得赞扬 
     —— 它见证了自00年代中期以来新数据库的技术爆炸(即NoSQL)。

在分布式系统开始兴起的这些年来,CAP定理帮助开发者去设计更复杂的架构。但是时至今日,我们再去看这个CAP定理的时候,不免发现他其实有一些误导的成分在其中。

分区容错性

CAP有时以这种面目出现:一致性,可用性和分区容错性:三者只能择其二。但事实上是,网络分区是一种不可避免的错误,他无论如何都有可能会发生。即使在像一家公司运营的数据中心那样的受控环境中,网络问题也可能出乎意料地普遍。

CAP定义的非常狭窄,它只考虑了一个一致性模型(即线性一致性,强一致性)和一种故障(网络分区,或活跃但彼此断开的节点)。它没有讨论任何关于网络延迟,死亡节点或其他权衡的事。许多所谓的“高可用”(容错)系统实际上不符合CAP对可用性的特殊定义。总而言之,围绕着CAP有很多误解和困惑,并不能帮助我们更好地理解系统,所以最好避免使用CAP,CAP对于设计系统而言并没有那么大的实际价值。

一致性

在一个线性一致性的系统里面,任何操作都可能在调用或者返回之间原子和瞬间执行
线性一致性,Linearizability,也称为原子一致性(atomic consistency),强一致性(strong consistency)等
也就是通常所说的 CAP 理论中的 C

虽然线性一致是一个很有用的保证,但实际上,线性一致的系统惊人的少。在大多数的时候牺牲线性一致性的原因是性能(performance),而不是容错。许多分布式数据库也是如此:它们是为了提高性能而选择了牺牲线性一致性,而不是为了容错。线性一致的速度很慢——这始终是事实,而不仅仅是网络故障期间。如果你想要线性一致性,读写请求的响应时间至少与网络延迟的不确定性成正比。

可用性

首先我们需要了解到,“可用性”是一个“活性”属性,也就是“最终可用性”,就像最终一致性一样。在某个时间点(例如,一个节点可能发送了一个请求,但还没有收到响应),它可能不成立,但总是希望在未来(即通过接受答复)。当你不得不在线性一致性和可用性之间做出选择的时候,比如可能遇到网络中断的场景,例如多地数据中心。

1, 使用多主数据库,每个数据中心都可以继续正常运行:由于在一个数据中心写入的数据是异步复制到另一个数据中心的,所以在恢复网络连接时,写入操作只是简单地排队并交换。2,如果使用单主复制,则主库必须位于其中一个数据中心。任何写入和任何线性一致的读取请求都必须发送给该主库,因此对于连接到从库所在数据中心的客户端,这些读取和写入请求必须通过网络同步发送到主库所在的数据中心。在单主配置的条件下,如果数据中心之间的网络被中断,则连接到从库数据中心的客户端无法联系到主库,因此它们无法对数据库执行任何写入,也不能执行任何线性一致的读取。它们仍能从从库读取,但结果可能是陈旧的(非线性一致)。如果应用需要线性一致的读写,却又位于与主库网络中断的数据中心,则网络中断将导致这些应用不可用。如果客户端可以直接连接到主库所在的数据中心,这就不是问题了,哪些应用可以继续正常工作。但直到网络链接修复之前,只能访问从库数据中心的客户端会中断运行。

独立思考

因为P总是不可避免 ,如果用仅仅用 CP 和 AP 来描述和设计系统,我认为并不合适。许多人对这些问题认真思考,并提出了术语和模型来帮助我们理解问题。比如关于副本一致性、事务隔离和可用性之间的联系。

每个系统设计的最终目的都是去创造一个可靠,可扩展和可维护的应用与系统。根据具体的业务场景,去设计自己的系统,而不应该花费太多精力在CAP原则。