拜托!这才是分布式系统CAP的正确打开方式!

Posted Hollis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拜托!这才是分布式系统CAP的正确打开方式!相关的知识,希望对你有一定的参考价值。

“纸面”上的CAP

相信很多同学都听过CAP这个理论,为了避免我们认知不同,我们先来统一下知识起点。

  • CAP理论在1999年一经提出就成为了分布式系统领域的顶级教义。并表明分布式服务中,存在三要素:一致性、可用性、分区容错性。而“CAP”就是Consistency/Availability/Partition Tolerance三个单词缩写。

    1. 一致性:分布式系统中,一份数据一般会存在多个副本,要求多副本数据对于数据的更新与单份数据相同,即强一致性

    2. 可用性:在任意的时刻,对分布式系统来说要保证在限定延时内正常响应客户端的读写请求,并且不会报错。(提前纠正一个误区,这里的可用性并不是咱们通常理解的服务的SLA可用性,即3个9、4个9之类的定义。实际上指的是是数据访问的可达性。)

    3. 分区容错性:在分布式服务中,节点之间网络通信异常导致(丢包、延迟、中断等)的网络分区现象是必然存在的,要保证出现网络分区现象时,分布式系统不受影响

  • 原论述表明CAP是不可以兼得的,一个系统需要放宽一点才能满足其他两点,因此此时对于分布式系统来说其实就三个选项CP、AP、CA三种,但是不能同时满足CAP。但是由于网络问题是不可避免的现象,所以预想的分布式系统都会往AP和CP上去权衡靠拢。如下所示:


CAP模型


  • 尝试沙盘推演分布式系统的CA、AP、CP选型
  1. 先说说CA选型
实际上CA选型对于我们来说并不陌生,Oracle和mysql数据库就是最好的例子,他们拥有强一致性和可用性,虽然Oracle RAC看似是分布式,但是依然选择节点本身的共享存储或者逻辑ASM存储;MySQL主从实际上可以理解成多个单点MySQL,通过Binlog数据同步逐渐将数据同步到所有单点上,写主读从,因此依旧是是单点的CA系统,舍弃了P。我们暂时不讨论数据库事务。这里我们主要还是聊聊正儿八经的分布式系统。
  2. 为什么CP系统不能满足A?
CP系统意味着是数据是单副本,分布在多个节点,如下图所示,D1-Dn代表着分布式系统的多个节点,当不同的Client访问节点上的数据时,由于不涉及副本数据的同步,每个节点都是最新的数据,数据必然是强一致性的。此时是满足C、P要素。但是此时如果发生网络分区问题,那么数据就必然丢失不可访问了,此时可用性A受到了影响。

拜托!这才是分布式系统CAP的正确打开方式!

  3. 什么AP系统不能满足C?
    AP系统意味着数据是有多副本的,即使出现网络分区问题,也不会丢失数据导致不可用,但是会存在数据一致性问题如下图所示,数据D1有3个副本,D1-1、D1-2、D1-3,并且分布在不同节点上。在T1时刻,正常情况下每个客户端读到的数据都是X=1,在T2时刻,Client1尝试将数据更新为X=2,接下来T3时刻请求到达分布式系统后端,将D1-1副本数据更新成功,但是在T4时刻数据副本D1-1和D1-2副本之间出现网络分区问题,D1-2并未被置成X=2,此时Client2和Client3读一份数据就出现了不同的返回值,虽然数据可达,但是由此带来了数据一致性问题。
    拜托!这才是分布式系统CAP的正确打开方式!
AP选型

 

在CAP中“迷失”

在上一节中我们解析了“纸面”上的CAP,按照其推论,分布式系统的世界看似很完美,绝大多数架构师也将CAP奉为第一原则,在设计系统之初就选择倾向于CP或者AP。即为了保证强一致性牺牲可用性或者为了可用性而降低一致性。
可是仔细一想,上一节所讲述的分布式世界真的这么完美吗?细细想来,误区太多了!
  • 误区一 "三选二"的先入为主
尽管网络问题在我们日常运营分布式系统中经常发生,但是相比正常时间,网络分区依然是小概率事件,因此并不应该在设计之处就放弃C或者A,在正常情况下分布式系统一定是要同时兼顾CAP
  • 误区二 CAP的定义极端
在上面的CAP理论中,分布式系统在网络分区的既定现实下一定会保证P,而在A、C中选取其一,但事实上A、C的选择并不是非黑即白的。因此上面的CAP理论过于粗旷笼统。
  1. 设计具体分布式服务时,实际上需要区分多个子模块,如计算模块/调度模块/存储模块等,在遭遇网络分区时,会实行将部分子模块降级等策略,从而细粒度取舍A和C,而不是直接影响整个服务、所有数据。
  • 误区三 CAP的标准模糊
CAP理论中只为C、A、P定义概念,但是却不定义标准,C、A、P3个要素都是定义在时间这个维度的基础上,一切都是基于时间视图,多长时间的数据算不违反一致性呢?多久的访问时间算影响数据访问的可用性呢?或者再较真一点,多久时间的网络问题算作网络分区呢?一切的本质都是时间。因此在理论基础上需要将CAP定性细分。
  1. 针对网络分区可以按照一定通信周期,分敛成单机网络分区、机器组网络分区(比如HDFS的机架感知实际上就是针对的就是后者);
  2. 针对一致性可以分成若干种一致性程度(后面的文章会讲到);
  3. 针对数据访问效率来说,按照P95/P99读写进行数据访问性能的进行区分也不失为一种手段。
  • 误区四 CAP理论是否要带Client玩?
CAP理论中并没有明确系统边界范围,一个分布式系统不包括Client那算什么分布式系统的呢?这里我们就来唠唠CAP理论为什么不包括Client。因为如果算上client的话,分布式集群将更为复杂。
  1. 假设网络分区发生在Cient和分布式服务中间,那么A肯定就无法达到了。
  2. 分布式服务一致性的效果就不是这么明显了,因为读请求都到不了分布式系统。
  3. 如果Client和分布式服务中间发生网络分区,此时分布式服务无论再怎么努力其实都是无用的。
虽然不带着Client玩,但并不意味着Client不需要重视,个人认为分布式系统的Client中一定要尽量保证CA,而不必去考虑P。

 

CAP的正确打开方式

上面提到了,由于传统CAP理论的存在一些误区点,其将很多同学带入错误的方向上,这里开始我们聊一聊CAP的正确打开方式。
  • CAP的目标状态

    拜托!这才是分布式系统CAP的正确打开方式!

如上图所示:在未发生网络分区的T1时刻,这时的分布式系统是同时满足CAP三要素的,各份数据一致性状态是S,当到了T2时刻,发生了网络分区情况,此时各个节点,会记录各个节点的状态S1、S2,当T3时刻网络分区恢复时,需要将S1、S2状态进行相应处理,这里的部分实际上是很多分布式服务的重点:比如可以通过log end offset(Kafka)或者transaction id(Zookeeper)在分区发生后进行leader比对选举,然后再进行数据同步。
  • 精细化CAP理论
CAP为我们打开了一扇大门,但是过于宽泛无法适合所有场景,比如不适合数据库事务,而强一致性C也会使得服务应用场景受限,因此理论需要细分领域,根据不同场景进行分类。
  1. ACID原则