谈一谈分布式系统中的CAP定理

CAP定理

以下来自百度百科的定义:

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

一致性(Consistency)

所谓一致性指的就是所有节点访问同一份最小的数据副本,分布式系统中的一份数据通常会保持多份,一致性要求在同一时刻无论访问哪一份数据都必须得到同样的值。

CAP定义中的一致性指的是强一致性。

举个例子

比如现在有两个节点,N1和N2,客户端向N1写入数据V1,当N1写完数据后如果直接返回给客户端写入成功,那么就不是强一致性了,因为此时可能客户端访问N2,得到的结果却不是V1。
那么强一致性下N1应当同时把数据V1同步给N2,并且等待N2返回成功,然后才能返回给客户端写入成功,此时无论客户端访问N1还是N2,得到的结果都是V1。

可以看出在强一致性的要求下,需要确保分布式系统中的所有节点的操作都必须同时成功,或者同时失败,很明显,这势必会对性能造成一定的影响,所以在实际应用中,多数会选择最终一致性的方式来在性能与一致性方面做权衡。

可用性(Availability)

所谓可用性是指每个请求不管成功或者失败都有响应,但是不能保证获取的数据是最新的数据。

分区容错性(Partition tolerance)

分区容错性指的是系统中任意信息的丢失或失败不会影响系统的继续运作,仍然能够对外提供一致性、可用性的服务。

分布式系统中,多个节点需要通过互相通信来传递某些信息,但网络是不稳定的,你必须考虑到信息丢失、延迟等异常状况,分区容错性需要能够应对当遇到这样的状况时,不会对分布式系统造成影响。

CAP三者不能同时满足

CAP原理的精髓就在于要么AP、要么CP、要么AC,就是不存在CAP。

选择AP,必须放弃C

选择了分区容错性也就意味着,允许节点之间信息的丢失,那么如果写消息到达了节点N1,但是节点N1同步给N2时,N2并没有收到,为了保证可用性,N1,N2必须继续做出响应,但此时N1,N2两个节点的数据已经是不一致性的了,所以保证了AP,就无法保证C。

选择CP,必须放弃A

和上面的例子一样的,如果要同时保证一致性和分区容错性,那在节点没有响应的情况下,只能让节点N1或者N2其中一个节点对外提供服务,这样才能即满足一致性又保证在节点之间不能互相通信的情况下继续对外提供服务,但此时可用性是无法保证的,因为你不能让N1和N2同时给出响应了。

选择CA,必须放弃P

如果两个节点N1和N2同时更新了数据,那么当然就可以同时对外提供服务,此时既保证了一致性又保证了可用性,但是一旦N1和N2之间出现了网络通信问题,那为了保证CA,唯一能做的就是停止数据的写入,保证现有的数据状态,只有这样才能满足CA,但这样就无法保证P了。

所以无论怎么CAP是无法同时满足的。

AP还是CP

很明显谁也无法100%保证网络间的通信不会出现任何问题,因此大多数架构设计都是在AP或者CP之间进行选择。

如果用ZK作服务发现与注册和Eureka对比,ZK就是基于CP的,Eureka就是基于AP的,ZK作为分布式协调服务,主要的职责就是保证服务之前数据一致,所以必须选择CP,而Eureka是专门作为服务注册与发现的组件的,所以选择AP更合适,那也就需要客户端自己的考虑不一致的情况。

从服务发现与注册的功能来看,选择AP架构应该是更合适的,在AP模式如果获取的服务实例信息有误,完全可以通过重试、重新负载等方式进行控制,而如果选择CP架构,导致得不到响应信息,那便会大大影响服务的处理能力。

所以AP还是CP还是需要结合实际的业务场景来选择的,而这也是架构设计的重要考量之一,而现在大多数都不会选择强一致性,而是采用最终一致性,这样在保证可用性的前提下还能在可接收的范围内保证数据的最终一致性。

Guess you like

Origin blog.csdn.net/CSDN_WYL2016/article/details/120711356