CAP理论的理解

分布式系统

拿一个最简单的例子,就比如说我们的图书管理系统。之前的系统包含了所有的功能,比如用户注册登录、管理员功能、图书借阅管理等。这叫做集中式系统。也就是一个人干了好几件事。

后来随着功能的增多,用户量也越来越大。集中式系统维护太麻烦,拓展性也不好。于是就考虑着把这些功能分开。通俗的理解就是原本需要一个人干的事,现在分给n个人干,各自干各自的,最终取得和一个人干的效果一样。

稍微正规一点的定义就是:一个业务分拆多个子业务,部署在不同的服务器上。 然后通过一定的通信协议,能够让这些子业务之间相互通信。

既然分给了n个人,那就涉及到这些人的沟通交流协作问题。想要去解决这些问题,就需要先聊聊分布式系统中的CAP理论。千万不要被这个看起来高大上的概念迷惑住。

CAP理论:

作为分布式系统的基础理论,描述的是一个分布式系统三个特性:

  • 一致性(Consistency):所有的节点上的数据时刻保持同步
  • 可用性(Availability):每个请求都能接受到一个响应,无论响应成功或失败
  • 分区容错性(Partition tolerance):系统应该能持续提供服务,即使系统内部有消息丢失(分区)

2002年,Lynch与其他人证明了Brewer猜想,从而把CAP上升为一个定理,对CAP的定义进行了更明确的声明。

C:一致性被称为原子对象,任何的读写都应该看起来是“原子“的,或串行的。写后面的读一定能读到前面写的内容。所有的读写请求都好像被全局排序。
A:对任何非失败节点都应该在有限时间内给出请求的回应。(请求的可终止性)
P:允许节点之间丢失任意多的消息,当网络分区发生时,节点之间的消息可能会完全丢失

最多只能实现其中的两个特性,不能三者兼顾。分布式系统要么满足AP,要么CA,要么CP。无法同时满足CAP。
CAP理论的理解_第1张图片
I. 一致性、可用性和分区容错性解析:

一致性:在分布式系统完成某写操作后任何读操作,都应该获取到该写操作写入的那个最新的值。相当于要求分布式系统中的各节点时时刻刻保持数据的一致性。

可用性: 一直可以正常的做读写操作。简单而言就是客户端一直可以正常访问并得到系统的正常响应。用户角度来看就是不会出现系统操作失败或者访问超时等问题。

分区容错性:指的分布式系统中的某个节点或者网络分区出现了故障的时候,整个系统仍然能对外提供满足一致性和可用性的服务。也就是说部分故障不影响整体使用。

事实上我们在设计分布式系统是都会考虑到bug,硬件,网络等各种原因造成的故障,所以即使部分节点或者网络出现故障,我们要求整个系统还是要继续使用的

(不继续使用,相当于只有一个分区,那么也就没有后续的一致性和可用性了)

II. 该怎么理解
如果我们事先保证了分区容错性,也意味着若某个节点故障了,用户还是可以继续访问。这时用户在访问过程中就会出现一致性和可用性不能同时满足的情况,参考下图:
CAP理论的理解_第2张图片
如图假设分布式系统有G1,G2两个节点,初始值都是v0。现在有一个client向系统写入了值v1,这里假设直接写的是节点G1。写完之后client再去读取这个值,这时读到了G2节点,

由于G2节点与G1节点失去连接,这时G1节点上的数据还未同步到G2节点,因此客户端读取到的是修改之前的值v0。 这就出现了不满足一致性的情况了。相当于满足了可用性,失去了一致性。

类似的,如果系统保证了强的一致性,那么在client 写完G1节点后, 而G1向G2节点同步数据出现了问题,这时如果client再去读取G2节点的数据时,client就会一直处于等待状态,因为系统内各节点

数据为同步上,需要等同步上才能使用。这就相当于满足了一致性,而失去了可用性。

CAP理论的理解_第3张图片
考虑多个客户端访问时,一致性和可用性还可以这么理解:假如client1 向G1 修改某个值的时候, 写操作还未完成,client2就发起来对该值的读操作,读的是G2节点,这时如果要满足一致性,

那么就得让client2 暂时无法使用,如果要让client2 使用,那么获取到的数据不是最新的,系统就不满足一致性。

III. CAP三者不可兼得,该如何取舍

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

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

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

权衡三者的关键点取决于业务

放弃了一致性,满足分区容错,那么节点之间就有可能失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会容易导致全局数据不一致性。对于互联网应用来说(如新浪,网易),机器数量庞大,节点分散,网络故障再正常不过了,那么此时就是保障AP,放弃C的场景,而从实际中理解,像门户网站这种偶尔没有一致性是能接受的,但不能访问问题就非常大了。

对于银行来说,就是必须保证强一致性,也就是说C必须存在,那么就只用CA和CP两种情况,当保障强一致性和可用性(CA),那么一旦出现通信故障,系统将完全不可用。另一方面,如果保障了强一致性和分区容错(CP),那么就具备了部分可用性。实际究竟应该选择什么,是需要通过业务场景进行权衡的(并不是所有情况都是CP好于CA,只能查看信息但不能更新信息有时候还不如直接拒绝服务)

你可能感兴趣的:(分布式)