如何正确理解分布式系统的CAP定理

CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。

要进一步理解定义,首选要建立的大前提是:客户端对分布式系统中的任意存活节点的访问,这里的存活是指节点是运行中的而不是崩溃/下线的。

一致性Consistency,它的要求无论访问任何节点,得到的结果要么都是一样的,要么被拒绝。

可用性Availability,它的要求无论访问任何节点,接口都是可用的,但不一定每个节点的结果都一样。

分区容错性Partition tolerance,这一项是分布式系统的特征,它要求当发生网络问题时,该分布式系统能够自我的修复依然形成分布式状态具有高可用特性。

为什么只能实现两点,我们以不同的分布式系统为例进行说明。

只能实现CP:典型系统Zookeeper

我们假设有5个节点组成的zk集群正在正常的为各个Client提供服务

 

然后在某个时间段发生网络问题,由于Zookeeper具有P特性,将会重新选举Leader形成新的集群,我们假设有3个节点组成了新集群,有2个节点不幸由于网络不畅通无法组进来

 

新的集群继续为Client提供服务,而红色节点由于脱离了集群,他们的数据将无法保持与集群一致,因此原本与这些节点通讯的Client将会被拒绝。

由此理解CAP我们可以看到Zookeeper是分布式系统,它首先具有P,另外当发生网络分区时,它承诺的是C,这必将要求脱离集群的节点不再提供服务,所以既然承诺了C就必定不能再具有A。

只能实现AP:典型系统Eureka

理解了CP的Zookeeper,要理解AP为什么不能实现C也就自然了。

Eureka在部署上我们继续参考上述zk集群

Eureka也具有P,当发生网络分区时,它承诺的是A,即客户端访问脱离集群的节点时依然提供服务,但可想而知黄色节点的数据将无法与新的集群保持一致,因此它是无法保障C特性的。

至于Eureka为什么选择容忍数据的不一致,跟注册中心的使用特点有关系,Eureka认为就注册中心这个场景上集群的整体可用性比服务注册列表数据的一致性更重要,各有各的需求和理解吧。

只能实现CA:典型系统Mysql

有没有没有P的系统,有,单机系统就是,例如Mysql。

有人说Mysql可以主备高可用啊,怎么是单机了?原因有多个。主备模式Client不能与任意Mysql节点进行读写;主备模式不是集群模式,出现故障时无法自我的组成新集群。是的,因为Mysql不是天然的分布式系统。

所以Mysql这样的系统,没有了P,就一定成为了CA,因为单机要么提供一致的可用的服务,要么崩溃/下线。