CAP原则
分布式–CAP原则
CAP理论是指分布式系统架构中通常只能够满足CAP三个指标中的两个,而不能同时满足CAP三个指标。
-
C(Consistency):一致性 一致性指的是All nodes see the same data at the same time,也就是说所有节点在同一时间看到的数据必须是一模一样的,比如足球比赛中,当比分发生了改变,客户端A看到的比分是1:0,而客户端B看到的比分还是0:0;又比如在银行系统中,通过微信进行银行卡转账,卡上余额从100变成了0,但是在支付宝中查看银行卡余额还是100,这显然就破坏了数据的一致性。
-
A(Avalilability):可用性 可用性指的是Reads and writes always succeed,也就是说无论是读操作还是写操作,始终是成功的,也就是服务一直可用,不存在服务失败或者用户操作失败的情况。比如说用户发起提现操作,过了会显示提现失败;在进行转账的时候提示了需要等2天后才能到账,显然就破坏了可用性,因为用户的一系列操作换来的是提现失败,转账延迟才能到账,而不是立马响应到账。
-
P( Partition Toleranc):分区容错性 分区容错性指all nodes look like one node,也就是说多个节点的运行看起来就像是一个节点在运行一样,一个节点宕机不可用,其他节点还可以正常运行。比如说某个应用程序在全国各地部署了10个节点,如果广州的节点宕机了,从而导致其他9个节点也不可用,这显然对于分布式系统来说是灾难性的,所以分布式的CAP的最先需要保证的也就是P,因为如果连P都实现不了,那么分布式就没啥意义了,因为部署多个节点除了分担单节点的压力之外,就是需要解决单节点宕机的情况下,其他节点可以继续提供正常的服务。
CAP三个指标无法共存。 一般来说 P 是前提。所以基本是CA里选,不是任意3选2.
为什么呢?P 意指分区容忍性。 这个分区容忍性什么意思,很多人容易望文生义,不要见风就是雨,理解成别的什么意思。所谓分区指的是网络分区的意思,这个一样还是容易望文生义。详细一点解释,比如你有A B两台服务器,它们之间是有通信的,突然,不知道为什么,它们之间的网络链接断掉了。好了,那么现在本来AB在同一个网络现在发生了网络分区,变成了A所在的A网络和B所在的B网络。所谓的分区容忍性,就是说一个数据服务的多台服务器在发生了上述情况的时候,依然能继续提供服务。所以显而易见的,P是大前提,如果P发生了,咱们的数据服务直接不服务了,还谈个毛的可用性和一致性呢。因此CAP要解释成,当P发生的时候,A和C只能而选一。举个简单的例子,A服务器B服务器同步数据,现在A B之间网络断掉了,那么现在发来A一个写入请求,但是B却没有相关的请求,显然,如果A不写,保持一致性,那么我们就失去了A的服务,但是如果A写了,跟B的数据就不一致了,我们自然就丧失了一致性。这里设计就涉及到架构师的选择了。注意这里的一致性是强一致性,意思是AB的数据时刻都是同步的,如果我们放弃了强一致性,不代表我们的数据就是一定是不一致的了,我们可以让A先写入本地,等到通信恢复了再同步给B,这就是所谓的最终一致性,长远的看我们的数据还是一致的,我们只是在某一个时间窗口里数据不一致罢了。如果这个时间窗口小过了用户逻辑处理的时间。那么其实对于用户来说根本毛都感觉不到。最终一致性有个很有意思的协议叫gossip就跟传八卦一个意思,我就把我收到里信息里我本地没有的部分加到我本地,再把这个信息发出去,那么长远的看,网络时好时坏,但是最终所有人都会有所有的信息。因此我们还是能够保证数据的最终一致性的。综上,CAP应该描述成,当发生网络分区的时候,如果我们要继续服务,那么强一致性和可用性只能2选1
看下面一个例子。
服务A和服务B,服务A数据x=0,服务B数据x=0,初始状态服务A和服务B都获取数据x=0,此时服务A将x的值更新成了1,而服务B此时的x还是等于0, 如果需要满足一致性,那么必须要在服务A更新本身数据的同时通知服务B也进行更新; 如果需要满足可用性,那么在用户调用服务A执行更新x值的时候就必须立刻返回更新成功的操作 如果需要满足分区容错性,就必须保存服务A和服务B任何一方异常了,不会影响服务的正常提供
那么如果出现服务A在通知服务B进行同步更新x的值的时候出现了网络异常会怎么样? 当服务A更新了x值之后,服务A和服务B之间网络异常无法及时通知服务B也就行x值的更新,而此时用户B来调用服务B的查询x值的操作。 如果需要满足一致性:那么服务B此时就不能立即给用户B返回x值,因为服务B的值是旧的,还没有更新成新的,那么就需要阻塞,知道网络正常之后再更新x值,此时就破坏了可用性,因为用户B的查询操作失败了或者是需要等待过长时间。 如果需要满足可用性:那么用户B调用服务B查询x值的时候就需要立即返回x值,也就是x=0的值,而此时服务A已经将x的值改成1了,所以就破坏了一致性的原则。 如果需要同时满足一致性和可用性,当服务A和服务B之间的通信出现异常时,就需要将整个服务设置成不可用,这样用户就不会在调用服务,数据也可在同步之后保持一致,但是也就破坏了分区容错性。
所以无论怎么实现,都只能尽量的满足CAP的三者,而无法保证三者同时绝对的满足。
CAP理论的舍弃方案 既然CAP无法三者共存,那么就需要对其中的1个进行舍弃掉。
舍弃C: 舍弃了一致性,也就是说允许同一时刻不同节点获取到的数据是不一样的,但是保证了高可用性,最典型的例子就是微信抢红包和12306系统,明明看到的红包是有的,打开就抢光了;明明看到还有票的,一点购买秒没了。这样的涉及虽然稍微牺牲了一点用户体验,但是对于系统做到了很好的保护,不会导致系统长期处于阻塞状态而慢慢瘫痪
舍弃A: 舍弃了可用性,也就是说允许用户操作失败,但是数据是绝对一致的,最典型的例子就是金融行业,在进行转账或提现的时候往往都不会立马告诉你操作成功,而是提示操作正在进行中,快的几分钟满的1-2个工作日才能正常到账,虽然舍弃了可用性,但是可以保证的是数据的绝对一致性,不可能会出现这里看到的余额是100,那里看到的余额是200的情况。
舍弃P: 舍弃了分区容错性,也就是说一个节点宕机了,整个系统就不可用了,但是可以保持一致性和可用性。不过对于分布式系统来说,如果舍弃了P,就会使得分布式系统黯然失色,因为分布式系统的两大优势就是分担压力和容错性高。
所以一般而言P是不可舍弃的,而需要舍弃的就是C和A,这个就需要针对系统的特点来选取方案,对于对数据很敏感的金融行业就必须保持数据的一致性,此时就需要舍弃A;而对于高并发下不能容忍用户操作频繁失败的情况,就需要舍弃一定的一致性,而保证可用性。比如一些新闻、微博类的展示类系统,对于数据一致性没有太高的要求,就可以优先保证可用性。
来源:CSDN
作者:bigeyescute
链接:https://blog.csdn.net/qq_39725929/article/details/104105145