分布式CAP理论


分布式CAP理论

来自wiki:php

理论计算机科学中,CAP定理(CAP theorem),又被称做布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来讲,不可能同时知足如下三点:[1][2]html

  • 一致性(Consistency) (等同于全部节点访问同一份最新的数据副本)
  • 可用性Availability)(每次请求都能获取到非错的响应——可是不保证获取的数据为最新数据)
  • 分区容错性Partition tolerance)(以实际效果而言,分区至关于对通讯的时限要求。系统若是不能在时限内达成数据一致性,就意味着发生了分区的状况,必须就当前操做在C和A之间作出选择[3]。)

根据定理,分布式系统只能知足三项中的两项而不可能知足所有三项[4]。理解CAP理论的最简单方式是想象两个节点分处分区两侧。容许至少一个节点更新状态会致使数据不一致,即丧失了C性质。若是为了保证数据一致性,将分区一侧的节点设置为不可用,那么又丧失了A性质。除非两个节点能够互相通讯,才能既保证C又保证A,这又会致使丧失P性质。node

来自:数据库

HollisChuang's Blog-Java干货集散地

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

不管你是一个系统架构师,仍是一个普通开发,当你开发或者设计一个分布式系统的时候,CAP理论是不管如何也绕不过去的。本文就来介绍一下到底什么是CAP理论,如何证实CAP理论,以及CAP的权衡问题。服务器

CAP理论概述

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

Teorema-CAP-2

读者须要注意的的是,CAP理论中的CA和数据库事务中ACID的CA并彻底是同一回事儿。二者之中的A都是C都是一致性(Consistency)。CAP中的A指的是可用性(Availability),而ACID中的A指的是原子性(Atomicity),切勿混为一谈。架构

CAP的定义

Consistency 一致性

一致性指“all nodes see the same data at the same time”,即更新操做成功并返回客户端完成后,全部节点在同一时间的数据彻底一致,因此,一致性,说的就是数据一致性。分布式的一致性并发

对于一致性,能够分为从客户端和服务端两个不一样的视角。从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。负载均衡

一致性是由于有并发读写才有的问题,所以在理解一致性的问题时,必定要注意结合考虑并发读写的场景。

从客户端角度,多进程并发访问时,更新过的数据在不一样进程如何获取的不一样策略,决定了不一样的一致性。

三种一致性策略

对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。

若是能容忍后续的部分或者所有访问不到,则是弱一致性。

若是通过一段时间后要求能访问到更新后的数据,则是最终一致性。

CAP中说,不可能同时知足的这个一致性指的是强一致性。

Availability 可用性

可用性指“Reads and writes always succeed”,即服务一直可用,并且是正常响应时间。

对于一个可用性的分布式系统,每个非故障的节点必须对每个请求做出响应。因此,通常咱们在衡量一个系统的可用性的时候,都是经过停机时间来计算的。

可用性分类 可用水平(%) 年可容忍停机时间
容错可用性 99.9999 <1 min
极高可用性 99.999 <5 min
具备故障自动恢复能力的可用性 99.99 <53 min
高可用性 99.9 <8.8h
商品可用性 99 <43.8 min

一般咱们描述一个系统的可用性时,咱们说淘宝的系统可用性能够达到5个9,意思就是说他的可用水平是99.999%,即整年停机时间不超过 (1-0.99999)*365*24*60 = 5.256 min,这是一个极高的要求。

好的可用性主要是指系统可以很好的为用户服务,不出现用户操做失败或者访问超时等用户体验很差的状况。一个分布式系统,上下游设计不少系统如负载均衡、WEB服务器、应用代码、数据库服务器等,任何一个节点的不稳定均可以影响可用性。

Partition Tolerance分区容错性

分区容错性指“the system continues to operate despite arbitrary message loss or failure of part of the system”,即分布式系统在遇到某节点或网络分区故障的时候,仍然可以对外提供知足一致性和可用性的服务。

分区容错性和扩展性紧密相关。在分布式应用中,可能由于一些分布式的缘由致使系统没法正常运转。好的分区容错性要求可以使应用虽然是一个分布式系统,而看上去却好像是在一个能够运转正常的总体。好比如今的分布式系统中有某一个或者几个机器宕掉了,其余剩下的机器还可以正常运转知足系统需求,或者是机器之间有网络异常,将分布式系统分隔未独立的几个部分,各个部分还能维持分布式系统的运做,这样就具备好的分区容错性。

简单点说,就是在网络中断,消息丢失的状况下,系统若是还能正常工做,就是有比较好的分区容错性。

CAP的证实

intro_thumb

如上图,是咱们证实CAP的基本场景,网络中有两个节点N1和N2,能够简单的理解N1和N2分别是两台计算机,他们之间网络能够连通,N1中有一个应用程序A,和一个数据库V,N2也有一个应用程序B2和一个数据库V。如今,A和B是分布式系统的两个部分,V是分布式系统的数据存储的两个子数据库。

在知足一致性的时候,N1和N2中的数据是同样的,V0=V0。在知足可用性的时候,用户无论是请求N1或者N2,都会获得当即响应。在知足分区容错性的状况下,N1和N2有任何一方宕机,或者网络不通的时候,都不会影响N1和N2彼此之间的正常运做。

scenario1_thumb

如上图,是分布式系统正常运转的流程,用户向N1机器请求数据更新,程序A更新数据库Vo为V1,分布式系统将数据进行同步操做M,将V1同步的N2中V0,使得N2中的数据V0也更新为V1,N2中的数据再响应N2的请求。

这里,能够定义N1和N2的数据库V之间的数据是否同样为一致性;外部对N1和N2的请求响应为可用行;N1和N2之间的网络环境为分区容错性。这是正常运做的场景,也是理想的场景,然而现实是残酷的,当错误发生的时候,一致性和可用性还有分区容错性,是否能同时知足,仍是说要进行取舍呢?

做为一个分布式系统,它和单机系统的最大区别,就在于网络,如今假设一种极端状况,N1和N2之间的网络断开了,咱们要支持这种网络异常,至关于要知足分区容错性,能不能同时知足一致性和响应性呢?仍是说要对他们进行取舍。

scenario2_thumb

假设在N1和N2之间网络断开的时候,有用户向N1发送数据更新请求,那N1中的数据V0将被更新为V1,因为网络是断开的,因此分布式系统同步操做M,因此N2中的数据依旧是V0;这个时候,有用户向N2发送数据读取请求,因为数据尚未进行同步,应用程序没办法当即给用户返回最新的数据V1,怎么办呢?

有二种选择,第一,牺牲数据一致性,保证可用性。响应旧的数据V0给用户;

第二,牺牲可用性,保证数据一致性。阻塞等待,直到网络链接恢复,数据更新操做M完成以后,再给用户响应最新的数据V1。

这个过程,证实了要知足分区容错性的分布式系统,只能在一致性和可用性二者中,选择其中一个。

CAP权衡

经过CAP理论及前面的证实,咱们知道没法同时知足一致性、可用性和分区容错性这三个特性,那要舍弃哪一个呢?

咱们分三种状况来阐述一下。

CA without P

这种状况在分布式系统中几乎是不存在的。首先在分布式环境下,网络分区是一个天然的事实。由于分区是必然的,因此若是舍弃P,意味着要舍弃分布式系统。那也就没有必要再讨论CAP理论了。这也是为何在前面的CAP证实中,咱们以系统知足P为前提论述了没法同时知足C和A。

好比咱们熟知的关系型数据库,如My Sql和Oracle就是保证了可用性和数据一致性,可是他并非个分布式系统。一旦关系型数据库要考虑主备同步、集群部署等就必需要把P也考虑进来。

其实,在CAP理论中。C,A,P三者并非平等的,CAP之父在《Spanner,真时,CAP理论》一文中写到:

若是说Spanner真有什么特别之处,那就是谷歌的广域网。Google经过创建私有网络以及强大的网络工程能力来保证P,在多年运营改进的基础上,在生产环境中能够最大程度的减小分区发生,从而实现高可用性。

从Google的经验中能够获得的结论是,没法经过下降CA来提高P。要想提高系统的分区容错性,须要经过提高基础设施的稳定性来保障。

因此,对于一个分布式系统来讲。P是一个基本要求,CAP三者中,只能在CA二者之间作权衡,而且要想尽办法提高P。

CP without A

若是一个分布式系统不要求强的可用性,即允许系统停机或者长时间无响应的话,就能够在CAP三者中保障CP而舍弃A。

一个保证了CP而一个舍弃了A的分布式系统,一旦发生网络故障或者消息丢失等状况,就要牺牲用户的体验,等待全部数据所有一致了以后再让用户访问系统。

设计成CP的系统其实也很多,其中最典型的就是不少分布式数据库,他们都是设计成CP的。在发生极端状况时,优先保证数据的强一致性,代价就是舍弃系统的可用性。如Redis、HBase等,还有分布式系统中经常使用的Zookeeper也是在CAP三者之中选择优先保证CP的。

不管是像Redis、HBase这种分布式存储系统,仍是像Zookeeper这种分布式协调组件。数据的一致性是他们最最基本的要求。一个连数据一致性都保证不了的分布式存储要他有何用?

在个人Zookeeper介绍(二)——Zookeeper概述一文中其实介绍过zk关于CAP的思考,这里再简单回顾一下:

ZooKeeper是个CP(一致性+分区容错性)的,即任什么时候刻对ZooKeeper的访问请求能获得一致的数据结果,同时系统对网络分割具有容错性。可是它不能保证每次服务请求的可用性,也就是在极端环境下,ZooKeeper可能会丢弃一些请求,消费者程序须要从新请求才能得到结果。ZooKeeper是分布式协调服务,它的职责是保证数据在其管辖下的全部服务之间保持同步、一致。因此就不难理解为何ZooKeeper被设计成CP而不是AP特性的了。

AP wihtout C

要高可用并容许分区,则需放弃一致性。一旦网络问题发生,节点之间可能会失去联系。为了保证高可用,须要在用户访问时能够立刻获得返回,则每一个节点只能用本地数据提供服务,而这样会致使全局数据的不一致性。

这种舍弃强一致性而保证系统的分区容错性和可用性的场景和案例很是多。前面咱们介绍可用性的时候说到过,不少系统在可用性方面会作不少事情来保证系统的整年可用性能够达到N个9,因此,对于不少业务系统来讲,好比淘宝的购物,12306的买票。都是在可用性和一致性之间舍弃了一致性而选择可用性。

你在12306买票的时候确定遇到过这种场景,当你购买的时候提示你是有票的(可是可能实际已经没票了),你也正常的去输入验证码,下单了。可是过了一会系统提示你下单失败,余票不足。这其实就是先在可用性方面保证系统能够正常的服务,而后在数据的一致性方面作了些牺牲,会影响一些用户体验,可是也不至于形成用户流程的严重阻塞。

可是,咱们说不少网站牺牲了一致性,选择了可用性,这其实也不许确的。就好比上面的买票的例子,其实舍弃的只是强一致性。退而求其次保证了最终一致性。也就是说,虽然下单的瞬间,关于车票的库存可能存在数据不一致的状况,可是过了一段时间,仍是要保证最终一致性的。

对于多数大型互联网应用的场景,主机众多、部署分散,并且如今的集群规模愈来愈大,因此节点故障、网络故障是常态,并且要保证服务可用性达到N个9,即保证P和A,舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到形成用户流程的严重程度。

适合的才是最好的

上面介绍了如何CAP中权衡及取舍以及典型的案例。孰优孰略,没有定论,只能根据场景定夺,适合的才是最好的。

对于涉及到钱财这样不能有一丝让步的场景,C必须保证。网络发生故障宁肯中止服务,这是保证CP,舍弃A。好比前几年支付宝光缆被挖断的事件,在网络出现故障的时候,支付宝就在可用性和数据一致性之间选择了数据一致性,用户感觉到的是支付宝系统长时间宕机,可是其实背后是无数的工程师在恢复数据,保证数数据的一致性。

对于其余场景,比较广泛的作法是选择可用性和分区容错性,舍弃强一致性,退而求其次使用最终一致性来保证数据的安全。这实际上是分布式领域的另一个理论——BASE理论。咱们下一篇文章再来介绍。

总结

不管你是一个架构师,仍是一个普通开发,在设计或开发分布式系统的时候,不可避免的要在CAP中作权衡。须要根据本身的系统的实际状况,选择最适合本身的方案。

参考资料:

CAP和BASE理论

CAP原理的证实

一文带你从新审视CAP理论与分布式系统设计

拓展阅读:

CAP理论

相关文章
相关标签/搜索