vlambda博客
学习文章列表

分布式CAS理论,BASE理论

CAS简介

CAP理论作为分布式系统的基础理论,它描述的是一个分布式系统在以下三个特性中:

  • 一致性(Consistency)

  • 可用性(Availability)

  • 分区容错性(Partition tolerance)


最多满足其中的两个特性。也就是下图所描述的。分布式系统要么满足CA,要么CP,要么AP。无法同时满足CAP。


特征

Consistency (一致性):

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


Availability (可用性):

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


Partition Tolerance (分区容错性):

即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。
分区容错性要求能够使应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。比如现在的分布式系统中有某一个或者几个机器宕掉了,其他剩下的机器还能够正常运转满足系统需求,对于用户而言并没有什么体验上的影响。


场景

       假设我们用一台服务器A对外提供存储服务,为了避免这台服务器宕机导致服务不可用,我们又在另外一台服务器B上运行了同样的存储服务。每次用户在往服务器A写入数据的时候,A都往服务器B上写一份,然后再返回客户端。一切都运行得很好,用户的每份数据都存了两份,分别在A和B上,用户访问任意一台机器都能读取到最新的数据。

这时不幸的事情发生,A和B之间的网络断了导致A和B无法通信,也就是说网络出现了分区,那么用户在往服务器A写入数据的时候,服务器A无法将该数据写入到服务器B。这时,服务器A就必须要做出一个艰难的选择:


       要么选择一致性(C)而牺牲可用性(A):为了保证服务器A和B上的数据是一致的,服务器A决定暂停对外提供数据写入服务,从而保证了服务器A和B上的数据是一致,但是牺牲了可用性。

注意:这里的可用性不是我们通常所说的高可用性(比如,服务器宕机导致服务不可用),而是指服务器虽然活着,但是却不能对外提供写入服务。

       要么选择可用性(A)而牺牲一致性(C):为了保证服务不中断,服务器A先把数据写入到了本地,然后返回客户端,从而让客户端感觉数据已经写入了。这导致了服务器A和B上的数据就不一致了。

——这就是CAP定理试图解释的问题。


CAP如何取舍:

(1) CA: 优先保证一致性和可用性,放弃分区容错。这也意味着放弃系统的扩展性,系统不再是分布式的,有违设计的初衷。

(2) CP: 优先保证一致性和分区容错性,放弃可用性。在数据一致性要求比较高的场合(譬如:zookeeper,Hbase) 是比较常见的做法,一旦发生网络故障或者消息丢失,就会牺牲用户体验,等恢复之后用户才逐渐能访问。

(3) AP: 优先保证可用性和分区容错性,放弃一致性。NoSQL中的Cassandra 就是这种架构。跟CP一样,放弃一致性不是说一致性就不保证了,而是逐渐的变得一致。


深入:

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

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

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

 


再深入

分布式系统无法放弃网络分区容忍性
网络分区准确地说是指两台机器无法在期望的时间内完成数据交换。这不仅仅是指两台机器之间的网络完全断开了,还可能有其他情况产生网络分区,比如对方机器宕机了,网络延时等情况。因此,在分布式系统中,通常是无法放弃Partition Tolerance的,也就只能在CP和AP之间做选择了。如果有个分布式系统号称是CA的,那一定是扯淡。


可用性和一致性的选择

可用性和一致性之间的选择不是非此即彼的,而是根据业务的需求在它们两者之间做妥协。比如,我们可以放弃对强一致性的追求,让其变成最终一致性,也就是说当服务器A不能把数据传给服务器B时,它先将数据缓存在其本地,等到网络恢复以后再将数据传给服务器B。这样,服务还是可用的,只是在一定的时间窗口内两者的数据是不一致的。


对网络分区的处理

对网络分区的处理有以下几个步骤:

  1. 检测网络是否出现分区

  2. 当分区出现了,进入分区模式并限制某些操作

  3. 当网络恢复后,启动分区恢复


从图中可见(图片来自 InfoQ),系统最开始是处于一致的状态S,然后分区出现了,每个分区的状态分别变成了S1和S2(这是为了保证系统的可用性,每个分区继续响应客户端的请求)。接着,网络恢复后开始分区合并,将S1和S2状态合并成为新的一致状态S‘。是不是看起来和代码版本管理很类似。


CAP总结

现如今,对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,节点只会越来越多,所以节点故障、网络故障是常态,因此分区容错性也就成为了一个分布式系统必然要面对的问题。 那么就只能在C和A之间进行取舍。 但对于传统的项目就可能有所不同,拿银行的转账系统来说,涉及到金钱的对于数据一致性不能做出一丝的让步,C必须保证,出现网络故障的话,宁可停止服务,可以在A和P之间做取舍。
总而言之, 没有最好的策略,好的系统应该是根据业务场景来进行架构设计的,只有适合的才是最好的。

 

BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的缩写,是CAP定理对应一致性与可用性权衡的结果。
BASE理论的核心思想是,即使无法做到强一致性,但每个系统都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。


  1. 基本可用:是指分布式系统在出现不可预知的故障时,允许损失部分可用性。例如响应时间的损失、功能上的损失

  2. 软状态:是指允许系统数据存在的中间状态,并认为该中间状态的存在不影响系统的整体可用性,及允许系统主机间进行数据同步的过程存在一定的延时。软状态,其实就是一种灰度状态,过渡状态。

  3. 最终一致性:其强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。


ZK与CP、Eureka与AP

        ZK遵循的是CP原则,即保证了强一致性,但牺牲了可用性。具体体现在:

  • 1、当ZK集群中的Leader宕机后,ZK集群会马上进行新的Leader选举。但选举时长一般在200毫秒内,最长不超过60秒,整个选举期间ZK集群是不接受客户端的读写操作的,即ZK集群处于瘫痪状态。

  • 2、Leader进行事务操作后,Follower节点会进行数据同步,这个同步时间然后很快,但是其同步过程也是不对我提供服务的。所以其不满足可用性。


Eureka遵循的是AP原则,即保证了可用性,但牺牲了一致性。