Skip to content

Latest commit

 

History

History
85 lines (47 loc) · 7.63 KB

大规模数据处理实战-09 CAP定理:三选二,架构师必须学会的取舍.md

File metadata and controls

85 lines (47 loc) · 7.63 KB

09 | CAP定理:三选二,架构师必须学会的取舍

在分布式系统的两讲中,我们一起学习到了两个重要的概念:可用性和一致性。而今天,我想和你讲解一个与这两个概念相关,并且在设计分布式系统架构时都会讨论到的一个定理——CAP 定理(CAP Theorem)。

他们在一篇论文中证明了:在任意的分布式系统中,一致性(Consistency),可用性(Availability)和分区容错性(Partition-tolerance)这三种属性最多只能同时存在两个属性。

C 属性:一致性

一致性在这里指的是线性一致性(Linearizability Consistency)。在线性一致性的保证下,所有分布式环境下Sever A、B、C 的状态始终是一致的。

img

A 属性:可用性

可用性的概念比较简单,在这里指的是在分布式系统中,任意非故障的服务器都必须对客户的请求产生响应。当系统满足可用性的时候,不管出现什么状况(除非所有的服务器全部崩溃),都能返回消息。

img

也就是说,当客户端向系统发送请求,只要系统背后的服务器有一台还未崩溃,那么这个未崩溃的服务器必须最终响应客户端。

P 属性:分区容错性

在了解了可用性之后,你还需要了解分区容错性。它分为两个部分,“分区”和“容错”。在一个分布式系统里,如果出现一些故障,可能会使得部分节点之间无法连通。由于这些故障节点无法联通,造成整个网络就会被分成几块区域,从而使数据分散在这些无法连通的区域中的情况,你可以认为这就是发生了分区错误。

img

如图所示,如果你要的数据只在 Sever A 中保存,当系统出现分区错误,在不能直接连接 Sever A 时,你是无法获取数据的。我们要“分区容错”,意思是即使出现这样的“错误”,系统也需要能“容忍”。也就是说,就算错误出现,系统也必须能够返回消息。分区容错性,在这里指的是我们的系统允许网络丢失从一个节点发送到另一个节点的任意多条消息。我们知道,在现代网络通信中,节点出现故障或者网络出现丢包这样的情况是时常会发生的。如果没有了分区容错性,也就是说系统不允许这些节点间的通讯出现任何错误的话,那我们日常所用到的很多系统就不能再继续工作了了。。

所以在大部分情况下,系统设计都会保留 P 属性,而在 C 和 A 中二选一。

论文中论证了在任意系统中,我们最多可以保留 CAP 属性中的两种,也就是 CP 或者 AP 或者 CA。关于具体的论证过程,如果你感兴趣的话,可以自行翻阅论文查看。

你可能会问,在我们平常所用到的开发架构中,有哪些系统是属于 CP 系统,有哪些是 AP 系统又有哪些是 CA 系统呢?我来给你介绍一下:

  • CP 系统:Google BigTable, Hbase, MongoDB, Redis, MemCacheDB,这些存储架构都是放弃了高可用性(High Availablity)而选择 CP 属性的。
  • AP 系统:Amazon Dynamo 系统以及它的衍生存储系统 Apache Cassandra 和 Voldemort 都是属于 AP 系统
  • CA 系统:Apache Kafka 是一个比较典型的 CA 系统。

放弃了 P 属性的 Kafka Replication

在 Kafka 发布了 0.8 版本之后,Kafka 系统引入了 Replication 的概念。Kafka Relocation 通过将数据复制到不同的节点上,从而增强了数据在系统中的持久性(Durability)和可用性(Availability)。在 Kafka Replication 的系统设计中,所有的数据日志存储是设计在同一个数据中心(Data Center)里面的,也就是说,在同一个数据中心里网络分区出现的可能性是十分之小的。

它的具体架构是这样的,在 Kafka 数据副本(Data Replication)的设计中,先通过 Zookeeper 选举出一个领导者节点(Leader)。这个领导者节点负责维护一组被称作同步数据副本(In-sync-replica)的节点,所有的数据写入都必须在这个领导者节点中记录。

小结

通过今天的学习,我们知道在 CAP 定理中,一致性,可用性和分区容错性这三个属性最多只能选择两种属性保留。CAP 定理在经过了差不多 20 年的讨论与演化之后,大家对这三个属性可能会有着自己的一些定义。例如在讨论一致性的时候,有的系统宣称自己是拥有 C 属性,也就拥有一致性的,但是这个一致性并不是论文里所讨论到的线性一致性。在我看来,作为大规模数据处理的架构师,我们应该熟知自己的系统到底应该保留 CAP 中的哪两项属性,同时也需要熟知,自己所应用到的平台架构是保留着哪两项属性。

思考题

如果让你重新设计微博系统中的发微博功能,你会选择 CAP 的哪两个属性呢?为什么呢?

AP,发微博保证最终一致性就可以。

有一个形象的比喻不知道恰当不恰当,一个系统相当于一个团队,

  • 有C属性说明这个团队每次都能保质保量完成任务,
  • A属性说明这个团队每次都能及时完成任务,
  • P属性相当于这个团队内部偶尔会犯一些小错误。

犯错是很常见的,所以一般都具有P属性。 CP类型的团队对外的形象相当于:我的团队不是完美的,但我的产品绝对不会出问题,只要你给我足够的时间让我们把问题排查清楚。 AP类型的团队给人的感觉就是:人非圣贤,孰能无过,我的队员会犯错,我的团队也有估计不足的时候,但是客户的需求我们总会最快响应。 CA类型的团队有个强人领袖(leader节点):任何事务无论大小都过问一遍,一旦发现手下有人犯错,立马剔除出团队,如果自己犯错,让出领袖地位,整个团队一定要保证最快最好完成任务。

文中提到的CA示例其实是有很强的误导性的。

首先我们要明确如下的事实: 1)对于一个分布式系统而言,节点故障和网络故障属于常态 2)如果出现网络故障,会造成节点分区 3)分布式系统在存在节点分区的情况下,C和A是冲突的

通过上面的事实我们可以推断出,如果想设计出一个CA系统,必须保证网络不出现分区才有可能,怎样保证网络不出现分区呢,一是单台机器,二是像例子中所述,将所有节点放在同个数据中心中可以假定网络出现分区的概率很低。这也是为什么例子中的情况可以假装称为CA。

还有一些需要辅助理解CAP的知识如下: 1)对于分布式系统而言,最简单可以分为两种,一是所有节点通过都可以通过某种策略对外提供服务,是对等的,二是所有节点通过一个master对外提供服务,甚至是一个单点的master 2)探讨系统CAP的前提应该是系统在能提供服务的情况下的CAP,如果存在master单点,但是有很多从属worker的话,这时的可用性探讨需要划分为worker故障和master故障来看。对于文中的例子master如果挂掉系统不可用则表名A其实也是勉强的

CAP Theorem is like the old joke about software projects: you can have it on TIME, in BUDGET, or CORRECT. Pick any two😀

CAP三者互相制衡,应该是看侧重哪两个,而不是选了哪两个,不是两个100分剩下的一个0分,本质上都要兼顾的。