前言

CAP、BASE等概念大家应该经常听过,本文主要对这些理论的学习总结,个人更倾向于想了解为什么会有这些理论,以及有什么用,因此会介绍它们的作用和应用。

CAP定理

定义

分布式系统的最大难点,就是各个节点的状态如何同步。CAP定理正是解决节点状态如何同步这个问题的基本定理,也是理解分布式系统的起点。
值得一提的是,涉及到节点同步才会涉及到CAP,比如无状态的机器就不存在CAP一说,而如ZooKeeper涉及到多个节点的数据同步,就会涉及到CAP
**
分布式系统有三个指标:Consistency、Availability、Partition tolerance。它们的首个字母分别是C,A,P

  • Consistency:即一致性。在分布式系统中,在一个节点写完后,在任意一个节点读数据,都能读到刚才写完的数据。
  • Avaliability:即可用性。意思是,只要收到客户端的请求,服务器(不管是哪个节点)必须给出回应,这个回应需要是明确的业务含义的,即请求处理结果成功或失败,而不能是无限等待或一个500之类的错误。
  • Partition tolerance:即分区容忍性。所谓分区容忍性,指的是网络发生分区时,还能继续提供服务(即容忍)。分区的含义举个例子,有S1、S2两台服务器,本来在同一个网络,但是现在它们之间网络连接断了,变成了两个网络,就出现了分区,出现分区时系统还能继续提供服务。

所谓指标就是希望能达到的目标,而CAP定理指的是这3个指标不能同时达到。

为什么成立

首先由于现在网络传输的现状,会出现挖断光缆等情况,导致网络分区是避免不了的。那如果P达不到,就意味着只能退化到单机的场景,就不能利用分布式的优势,因此P肯定要达到。那CAP定理就演化成了,C和A不能同时达到。
那为什么C和A不能同时达到呢?假设系统中有5个节点n1-n5,n1-n3在物理机房A,n4-n5在物理机房B,此时发生了网络分区,机房A与B网络不互通:

  • 为了一致性,机房A写入成功,但同步机房B失败,会导致整个请求写失败,就失去了可用性。
  • 为了可用性,机房A可以写入成功,但又会导致机房A与机房B的数据出现不一致。因此C和A不能同时达到。

BASE

BASE是对CAP定理中C和A权衡的结果。核心思想是即使为了A无法做到强一致性,也可以通过手段达到最终一致性。BASE拆解如下:
BA:Basic Available 基本可用。出现不可预知故障时,允许牺牲部分可用性,如响应时间增大
S:Soft state 软状态。允许系统中的数据存在中间状态,比如数据副本同步时存在延迟,该状态不影响可用性
E:Eventually consistent 最终一致性。经过一段时间后,数据副本能达到一致。

CAP与BASE的出现和彼此之间的关系,简单来说是,分布式系统存在节点状态要同步,会存在CAP不能同时达到的情况。对于P是需要保证的,因此要考虑CA之间的权衡,BASE主要提出了在保证A的情况下做最终一致的权衡方式。

应用场景

ZooKeeper

对于ZK来说,是CP的,其中一致性是顺序一致性(最终一致的一种)。之所以是最终一致,是因为leader/follower同步机制下,一半以上节点写入成功则代表写入成功,这时可能存在部分节点还不是最新的数据。所谓顺序一致性是每个节点的数据都是严格按照事务发起的顺序生效的。
ZooKeeper不保证每次请求的可用性,比如在Leader选举过程中或者半数以上的机器不可用的时候服务就是不可用的。

Eureka

保证的则是 AP。 Eureka 在设计的时候就是优先保证 A(可用性)。在 Eureka 中不存在什么 Leader 节点,每个节点都是一样的、平等的。因此 Eureka 不会像 ZooKeeper 那样出现选举过程中或者半数以上的机器不可用的时候服务就是不可用的情况。 Eureka 保证即使大部分节点挂掉也不会影响正常提供服务,只要有一个节点是可用的就行了。只不过这个节点上的数据可能并不是最新的。

Nacos

同时支持CP/AP。对于服务注册信息等数据的同步使用Distro协议来实现AP,对于命名空间等数据的同步使用Raft协议来实现CP。

参考链接