CAP定理指在设计分布式系统时,一致性(Consistent)、可用性(Availability)、Partition Tolerance(分区容忍性)三个属性不可能同时满足,该定理也叫做布鲁尔定理。CAP定理明确了分布式系统所能实现系统的局限性,目前互联网中的很多分布式系统是基于首要满足可用性和分区容忍性而设计的。在这里,不打算提及目前火热的Cassandra、Voldemort等分布式存储系统,而是打算介绍一下CAP定理。
形式化描述
一致性 :所有在分布式系统上的操作有一个总体上的顺序,每一个操作看起来就像是在一个单独的瞬间完成的。这就要求分布式系统的运行就像是在一个单节点上一样,在一个时间响应一个操作。
可用性 :对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。也就是,该系统使用的任何算法必须最终终止。当同时要求分区容忍性时,这是一个很强的定义:即使是严重的网络错误,每个请求必须终止。
分区容忍性 :为了定义分区容忍性,假定网络满足如下条件:网络是可能丢失从一个节点发往另一个节点的任意消息,当网络被分区(隔断)时,所有从一个分区的节点发往另一个分区的消息将会丢失。一致性要求每个响应必须是一致的,即使系统内部的消息没有被正确地发送。可用性要求从客户端接收请求的任一节点必须被响应,即使任意的消息可能没有被正确地发送。
异步网络
在异步网络模型中,没有统一时钟,所有节点仅根据接收到的消息和本地的计算进行决策。
定理一:
在一个异步网络模型中,没有可能实现一个满足以下属性的读写数据对象:
1、可用性
2、一致性
对于所有对等运算(包括消息会丢失的)
证明:
假设存在一个算法A满足这些条件:一致性、可用性、分区容忍性。我们构造一次A的执行,包括一个返回非一致结果的请求。假设网络包含至少两个节点,那么它可以被分为不相关的非空集合:{G,H}。假设所有G和H之间的通讯消息都丢失,这是可能的。如果这时在G上有一个写操作,接着H上有一个读操作,那么读操作将无法返回早些的写操作。■
推论一:
在一个异步网络模型中,没有可能实现一个满足以下属性的读写数据对象:
1、可用性,所有对等运算
2、一致性,所有对等运算,但消息不会丢失
证明:
形式化描述
一致性 :所有在分布式系统上的操作有一个总体上的顺序,每一个操作看起来就像是在一个单独的瞬间完成的。这就要求分布式系统的运行就像是在一个单节点上一样,在一个时间响应一个操作。
可用性 :对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。也就是,该系统使用的任何算法必须最终终止。当同时要求分区容忍性时,这是一个很强的定义:即使是严重的网络错误,每个请求必须终止。
分区容忍性 :为了定义分区容忍性,假定网络满足如下条件:网络是可能丢失从一个节点发往另一个节点的任意消息,当网络被分区(隔断)时,所有从一个分区的节点发往另一个分区的消息将会丢失。一致性要求每个响应必须是一致的,即使系统内部的消息没有被正确地发送。可用性要求从客户端接收请求的任一节点必须被响应,即使任意的消息可能没有被正确地发送。
异步网络
在异步网络模型中,没有统一时钟,所有节点仅根据接收到的消息和本地的计算进行决策。
定理一:
在一个异步网络模型中,没有可能实现一个满足以下属性的读写数据对象:
1、可用性
2、一致性
对于所有对等运算(包括消息会丢失的)
证明:
假设存在一个算法A满足这些条件:一致性、可用性、分区容忍性。我们构造一次A的执行,包括一个返回非一致结果的请求。假设网络包含至少两个节点,那么它可以被分为不相关的非空集合:{G,H}。假设所有G和H之间的通讯消息都丢失,这是可能的。如果这时在G上有一个写操作,接着H上有一个读操作,那么读操作将无法返回早些的写操作。■
推论一:
在一个异步网络模型中,没有可能实现一个满足以下属性的读写数据对象:
1、可用性,所有对等运算
2、一致性,所有对等运算,但消息不会丢失
证明:
主要问题是在异步网络模型中一个算法没有办法去判断一个消息是否丢失或者在传输通道中被延迟。因此,如果在运算中不会丢失任何消息的前提下存在一个能够保证一致性的算法,那么该算法也能够在所有运算(消息可能丢失)情况下保证一致性。这将与定理一矛盾。■
Brewer教授当时想象的分布式场景是webservice,一组websevrice后台运行着众多的server,对service的读写会反应到后台的server集群,并对CAP进行了定义:
- C(一致性):所有的节点上的数据时刻保持同步
- A(可用性):每个请求都能接受到一个响应,无论响应成功或失败
- P(分区容错):系统应该能持续提供服务,即使系统内部有消息丢失(分区)
高可用、数据一致是很多系统设计的目标,但是分区又是不可避免的事情:
- CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。
- CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。
- AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。
CAP的出现仿佛是一盏明灯,它揭露了分布式系统的本质,并给出了设计的准则,而这正是1985年以来人们正在寻找的东西!所以CAP在当时的影响力是非常大的!
【总结】我们研发的分布式通讯系统本质上是AP without C, 允许暂时的不一致并追求最终的一致性。