最近跟项目组的同事封闭开发搞项目,偶尔发起一下头脑风暴,涉及到MQ的一个问题,然后就发起了一次关于分布式一致性问题的讨论,于是就说起了CAP理论和BASE理论,趁着这个机会回顾下自己的知识。
首先CAP原则和BASE理论讲的都是在一个分布式系统中各个节点的状态如何同步,从而产生的解决理论。
CAP原则
CAP原则是三个名词的定义的缩写,分别代表:Consistency、Availability、Partition tolerance。即一致性、可用性、分区容忍性。
CAP原则的结果就是在分布式系统中最多只能达成两个指标,无法三个指标都实现。
那个三个指标是如何定义分析的呢?
C:Consistency,一致性要怎么理解呢?要理解一致性前提是在分布式系统环境下,假设在分布式系统中有两个相同的服务service1,service2,有一个用户customer,如果customer向service1发起一个更新请求,修改service1中的value=1,然后该用户再去发起一条向service1的查询,查询到的value应该也是1,那么这样就能满足一致性(查询即更新的值)。但是因为在分布式系统中,因此用户customer可能出现向service2发起一个查询请求,那么拿到的值不是1,那么就无法满足一致性。
因此基于这种情况,在customer发起修改service1的值为1时,service1需要向service2发起一条通知消息,告诉service1,我的值已经被修改为了1,那么即使customer向service2发起查询请求时查询到的值依然是1,这样就保证了在分布式系统中的一致性。
A:Availability,可用性的理解比一致性要简单,也是在分布式系统中,一个用户向每个服务发起请求,每个服务都要给出回应,这样才能满足可用性(即每个服务都是可用的),如果服务不能给出响应,那么就无法满足可用性。
P:Partition tolerance,分区容忍性的解释需要从网络方面进行考虑,在分布式系统中,每个服务可能部署在不同的地区,网络中又存在分区的概念,比如中国区,美国区、香港区等等,如果在分布式系统中一个服务部署在中国区,一个系统部署在美国区,两个服务之间的通信是跨区通信,存在通信失败的可能,因此在分布式系统中是否容忍这种跨区通信失败的问题,如果容忍那么就满足分区容忍性,如果不能则不满足分区容忍性。
前面说到最多只能达成两个指标,但是其实可用性和一致性并不能同时满足,这又是为什么?
其实通过反推法可以证明这个问题,假设在分布式系统中可以满足可用性和一致性,那么就需要分布式系统中的每个服务可以响应用户的请求同时也要满足一致性,那么根据前面一致性的问题可以知道如果要满足分布式系统的一致性就需要service1通知service2自己更新的值,那么service2就要保证在处理收到service1的通知期间不能处理任何的读写请求,这样就与可用性相悖,再做一个假设如果service2在处理service1通知期间允许读写请求,那么就导致service2处理的请求不满足一致性。从以上的反证法推论就可以知道在一个分布式系统中一致性和可用性只能满足一个。
所以基于以上的理论可以知道一个分布式系统要么满足一致性和分区容忍性,要么满足可用性和分区容忍性。也就是我们平时说的AP(可用性+分区容忍性)和CP(一致性+分区容忍性)。
那么各自的代表有什么呢?以AP为例最经典的就是Eureka,以CP为例则是zookeeper。
BASE理论
说完了CAP再来说BASE理论。BASE理论是对CAP的一个扩展,因为在CAP原则中只强调一致性,并且这个一致性是强一致性,也就是要么满足一直要么不满足一致,但是BASE理论则对这种强一致性做中和,也就是在BASE理论中可以理解为在实现过程中可以不要求强一致性,只要最终的结果满足一致性即可,即最终一致性,因此在BASE理论中我理解的核心就是最终一致性。
那么BASE理论指的什么呢?BASE理论也是几个名词的拼接,分别是Basic Available、Soft state、Eventually consistent。
-
Basic Available:基本可用。基本可用指的是在分布式系统中可以容忍一些问题,比如当用户向service2发出请求,规定的响应时间为100ms,但是service2需要保证与service1的一致性,那么就可能会导致service2处于短暂的同步期,那么响应时间可能会变成2s,那么在这个时间在可接受范围内,是可以容忍这种情况的发生。保证服务的基本可用,而不是直接返回服务不可用。
-
Soft state:软状态。软状态可以理解为中和强一致性的一种中间状态,即在实现最终一致性时,由于不可抗力因素导致无法直接达成最终一致性,那么就可以通过一种软状态来中和。比如用户向service2发出请求,要求修改数据value=2,但是其他服务也会修改该value,因此这个value在多个服务之间存在不同的副本,但是如果我们将所有修改value值的请求都最终作为一个分布式事务进行考虑,那么每个服务修改value的值都是一种软状态,只有最后一个要修改成功该value的值即可。软状态的存在可以保证整个服务的可用并且最终的结果是预期的。
-
Eventually consistent:最终一致性。前面说的两个最终都是达成该目标而做的优化,最终一致性讲的就是在分布式系统中只要完成对数据的最终结果达到预期,中间的经过可以不考虑,只要最终结果是ok的,那么这个系统就是满足要求的。举个例子来说,在物流方面需要控制物流订单的状态,比如揽收、分拨、到达,那么在处理订单状态时可以容忍分拨比揽收先处理,但是状态不可逆,这样最终的订单状态是到达就可以满足控制订单的处理要求。
总结
以上就是自己对CAP以及BASE的理解,在平时开发中可以通过实际业务场景从中选择适合的方式进行实现,比如在实际开发中我经常使用MQ做异步处理,但是并不是盲目的直接使用,而是要考虑需要处理的业务是否要求一致性,如果中间态的变更对实际业务没有影响,那么可以使用只要保证BASE中的最终一致性即可,但是如果该业务需要强一致性控制后续流程,那么就要考虑其它方案进行实现。
以上就是自己的一些理解,若有错误,欢迎斧正。