CAP原则介绍

  CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

CAP的三个指标

  

java ctp使用 java中的cap_数据

  一致性(Consistency)

  “all nodes see the same data at the same time”,即更新操作成功并返回客户端后,所有节点在同一时间的数据完全一致,这就是分布式的一致性。一致性的问题在并发系统中不可避免,对于客户端来说,一致性指的是并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致

  可用性(Availability)

  可用性指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。

  分区容错性(Partition tolerance)

  即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。

CAP定理的证明

  以下说明为什么CAP 原则三个要素最多只能同时实现两点,不可能三者兼顾。

  假设有一个客户端C用户A,2台服务器,分别部署了2个同样的服务节点S1、S2,存放的数据都是V0,他们之间的网络可以互通,也就相当于分布式系统的两个部分。

  

java ctp使用 java中的cap_数据_02

  操作流程

更新了数据V1到S1

  2、S1节点这个消息告诉S2节点,想让S2页更新数据,却发生了网络故障,S2中保存的还是V0

  3、客户端向S2请求数据,S2返回V0数据

  分析

  (1)系统网络发生了故障,但是系统依然可以访问,因此具有容错性。

  (2)客户端A访问节点S1的时候更改了V0到V1,想要客户端A访问节点S2的时候是V1,因此需要等网络故障恢复,将S2节点的数据进行更新才可以。

  (3)在网络故障恢复的这段时间内,想要系统满足可用性,是不可能的。因为可用性要求随时随地访问系统都是正确有效的。这就出现了矛盾。

  正是这个矛盾所以CAP三个特性肯定不能同时满足。既然不能满足,那我们就进行取舍。  

  有二种选择:

    第一,牺牲数据一致性,响应旧的数据V0给客户端;

    第二,牺牲可用性,阻塞等待,直到网络连接恢复,数据更新操作完成之后,再给用户响应最新的数据V1。

取舍策略

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

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

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

  一般来说,分区容错无法避免,因此可以认为 CAP 的 P 总是成立。CAP 定理告诉我们,剩下的 C 和 A 无法同时做到。