CAP理论是在分布式集群环境下讨论的,为什么分布式集群环境下会存在CAP问题呢?举个例子,假设我们后端存储服务使用Redis中间件,如果只部署一台Redis服务器,那么这台Redis如果挂了,整个存储服务都挂了,那么我们就想要提高它的可用性,怎么办呢?最简单的方法就是加机器:
可用性:
简单来说就是通过搭建集群来防止单机部署服务出现问题后,整个系统直接不可用,通过搭建高可用集群来防止某一个节点宕机后,其他几点一样可以继续提供服务。如redis的高可用集群,当某一个主节点宕机后,可以通过其他节点来提供服务
一致性:
一致性又可以分为强一致性,弱一致性,最终一致性,其中这里所指的一致性表示强一致性,要保证同一时刻读取的数据要一致。比如说某一时候客户端向服务更新一条数据(set key =1 原始 key值是0),然后客户端执行读取操作,这时应该保证读取的数据是1而不应该是0(因为集群情况下set更新请求的服务器和read读取的服务器不是同一台)
分区容忍性:
分区是指,在分布式系统中,不同的节点分布在不同的子网络中,由于一些特殊的原因,这些子节点之间出现了网络不通的状态,但他们的内部子网络是正常的。从而导致了整个系统的环境被切分成了若干个孤立的区域,这就是分区。
当你一个数据项只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。提高分区容忍性的办法就是一个数据项复制到多个节点上,那么出现分区之后,这一数据项就可能分布到各个区里,容忍性就提高了。
下面结合图来分析 为什么一定要保证分区容忍性,现在我们先假设不保证分区容忍性,保证AC,如图所示:
如果发生分区时,很明显集群不对外提供服务,这一点肯定是不符合我们的设计的,只有在不出现分区时,才可以提供服务。但是集群服务很难保证(基本上不可能 ,高可用服务肯定是集群部署)。
保证分区可用性时,在集群部署时分析如下:
如果保证P,说明集群就只能从A和C选择其一,为什么呢?我们重点看上图中的第四步,在B节点read num值的操作。
CP:若此时不让客户端读取B节点的num值,那么此时不可用,只能让客户端读取A节点,在A节点中M值确实是客户端Set num = 1值,num值一致,此时是CP模型,可用性被舍弃。
AP:若此时可以让客户端读取B节点的num值,那么此时节点可用,但是读取到的值num=0,如果下次又来一个客户端读取A节点的num值,却读到了num=1,Mnum值不一致,此时是AP模型,一致性被舍弃
CAP参考:分布式理论(一) - CAP定理 - 掘金
为什么Nacos配置中心要使用CP模型?
CP模型牺牲了一定的延时去换取数据的强一致,但应用的外部化配置并不要求配置成功的延迟要多低,更多的是要保证配置信息的一致性(我配置信息 A = 1,不要给我弄丢了或者等下查 A 不等于 1,造成 X 服务 A = 1,Y 服务 A = 0 情况发生,这些都是数据不一致,这肯定是不行的),所以在这种配置场景下是十分适合做CP模型的
为什么Nacos注册中心要使用AP模型?
这个问题也可以转换成为什么注册中心要使用AP模型。因为可用性比一致性更加重要,可用性体现在两个方面,第一是容许集群宕机数量,AP模型中集群全部机器宕机才会造成不可用,CP模型只容许一半的机器宕机。第二是分区是否可写,例如A机房和B机房发生分区,无法进行网络调用,在CP模型下部署在A机房的服务就无法部署,因为A机房无法与B机房通讯,所以无法写入IP地址,在AP模型下,可以去中心化,就像Eureka那样就算发生分区每台机器还都能写入,集群间无Master,而是互相复制各自的服务IP信息,这样,在分区时依然是支持写入的。不可用会造成微服务间调用拿不到IP地址,进而业务崩盘,所以不可用是不可接受的,不一致会造成不同微服务拿到的IP地址不一样,会造成负载不均衡,这是可以接受的。
BASE理论是Basically Available(基本可用),Soft State(软状态)和Eventually Consistent(最终一致性)三个短语的缩写。BASE是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网分布式系统实践的总结,是基于CAP定律逐步演化而来。其核心思想是即使无法做到强一致性,但每个应用都可以根据自身业务特点,才用适当的方式来使系统打到最终一致性。