分布式理论 - CAP

概念

CAP 定理(CAP theorem)又被称作「布鲁尔定理」,是加州大学伯克利分校的计算机科学家埃里克·布鲁尔(Eric Brewer)在 2000 年的 ACM PODC 上提出的一个猜想。2002 年,麻省理工学院的赛斯·吉尔伯特(Seth Gilbert)和南希·林奇(Nancy Lynch)发表了布鲁尔猜想的证明,使之成为分布式计算领域公认的一个定理。

CAP

CAP理论

第一版:对于一个分布式计算系统,不可能同时满足一致性、可用性、分区容错性三个设计约束。

第二版:在一个分布式系统(指互相连接并共享数据的节点集合),当涉及读写操作时,只能保证一致性、可用性、分区容错性三者中的两个,另外一个必须被牺牲

两版本差异点:

  1. 第二版强调互连和共享数据。因为分布式系统并不一定存在互连和共享数据,例如Memcached 集群为代表的不互相通信的分布式缓存
  2. 第二版强调读写操作,CAP关注的是对数据的读写操作,而不是分布式系统所有的功能

一致性(Consistency)

第一版:所有节点在同一时刻都能看到相同的数据。

第二版:对于指定客户端而言,读操作保证能够返回最新的写操作结果。

可用性(Availability)

第一版:每个请求都能得到成功或失败的响应。

第二版:非故障的节点在合理的时间内返回系统的正常响应(不是错误和超时的响应)。

分区容错性(Partition tolerance)

第一版:尽管出现消息丢失或分区错误,但系统仍然能够继续运行。

第二版:当系统中某个节点或网络分区出现后,整个系统仍然能对外提供满足一致性和可用性的服务(部分故障不影响整体使用)。

CAP应用

在这个理论中,最多只能同时做到其中的两个特性,要么满足CA、要么满足CP,要么满足AP。同时满足 CAP 是不可能的。而且实际在分布式环境下,必须选择P。因此,分布式系统理论不可能选择CA,只能选择CP或AP。

CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但放弃P的同时也就意味着放弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点,这是违背分布式系统设计的初衷的。传统的关系型数据库RDBMS:Oracle、MySQL就是CA。

CP without A:如果不要求A(可用),相当于每个请求都需要在服务器之间保持强一致,而P(分区)会导致同步时间无限延长(也就是等待数据同步完才能正常访问服务),一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。设计成CP的系统其实不少,最典型的就是分布式数据库,如Redis、HBase等。对于这些分布式数据库来说,数据的一致性是最基本的要求,因为如果连这个标准都达不到,那么直接采用关系型数据库就好,没必要再浪费资源来部署分布式数据库。

AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。典型的应用就如秒杀活动,可能前几秒你浏览商品的时候页面提示是有库存的,当选择完商品准备下单时,系统提示下单失败,商品已售完。这其实就是先在 A(可用性)方面保证系统可以正常的服务,然后在数据的一致性方面做了些牺牲,虽然多少会影响一些用户体验,但也不至于造成用户购物流程的严重阻塞。

CAP细节

  • CAP关注的粒度是数据,而不是整个系统

    • 整个系统,可能既存在CP,又存在AP
  • CAP是忽略网络延迟的

    • 因为网络延迟是客观存在的,那么技术上是无法做到分布式场景下完美的数据一致性
    • 单个账户的信息无法做到CP,只能CA,然后通过复制实现同步
  • 正常运行情况下,不存在CP和AP的选择,可以同时满足CA

    • 没有发生分区,那么应该C和A是都可以保证的,用户账号数据也可以采用消息队列的方式实现CA
  • 放弃并不等于什么都不做,需要为分区恢复后做准备

    • CAP中牺牲一个,并不是什么都不做,例如分区期间记录日志,以用于分区故障解决后,重新使得系统得到CA状态。