系统的数据一致性到底是在说什么?我到今天才算真明白了( 三 )


分布式架构有很多相关的理论和算法 , 这里我只说了CAP、BASE理论 , 其他诸如Paxos算法、Raft算法、ZAB协议等等 , 这些大家自己找资料看看吧!
我们先来说说CAP理论
这个CAP理论相信很多人都听说过 , 下面请允许我写下教科书般的理论内容:
CAP原则又称CAP定理 , 指的是在一个分布式系统中 , Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性) , 三者不可得兼 。
一致性(C):在分布式系统中的所有数据备份 , 在同一时刻是否同样的值 , 也就是等同于所有节点访问同一份最新的数据副本 。可用性(A):保证每个请求不管成功或者失败都有响应 , 即使数据不是最新的 。分区容忍性(P):系统中的某个节点或者网络分区出现了故障的时候 , 整个系统仍然能对外提供的服务 。
什么情况?这个CAP理论上来就给出三个概念或者说是指标 , 还说分布式系统只能满足上面两个指标 。大家是不是经常听到CAP理论 , 但是却又不是很理解为什么CAP三个指标只能满足其中的两个 , 那么接下来我给大家解释一下:
就如前面的“分布式架构图”展示的一样 , 系统一个对外的服务涉及到多个节点通讯和交互 , 节点所处的网络发生分区故障的问题又无法避免 , 所以分布式系统中分区容错性必须要考虑 , 那么系统自然也不可能同时满足上面说的三个指标 。
分布式系统中CAP如何抉择?
在分布式系统内 , 各种因素导致分区是必然的会发生的 , 不考虑分区容忍性(P) , 一旦发生分区错误 , 整个分布式系统就完全无法使用了 , 这其实和最开始的单体应用一样有单点问题 , 这样的系统是和分布式架构理论是相违背的 , 同时也是不符合实际需要的 。所以 , 对于分布式系统 , 我们只能能考虑当发生分区错误时 , 如何选择一致性(C)和可用性(A) 。
根据一致性和可用性的选择不同 , 开源的分布式系统往往又被分为 CP 系统和 AP 系统 。当系统在发生分区故障后 , 客户端的任何请求都被阻塞或者超时 , 但是 , 系统的每个节点总是会返回一致的数据 , 则这样的系统就是 CP 系统 , 经典的比如 Zookeeper 。当系统发生分区故障后 , 客户端依然可以访问系统 , 但是获取的数据是不一致的 , 有的是新的数据 , 有的还是老数据 , 那么这样系统就是 AP 系统 , 经典的比如 Eureka 。
前面说分布式系统不考虑分区容忍性(P)为啥分区错误发生 , 系统就不能用了 , 这里我再解释一下: 不考虑分区容忍性(P) , 那就是选择CA 。假设发生了分区错误 , 系统由于可用性(A)的要求 , 即使系统发生分区故障也要提供服务 , 那系统就仍然向外提供服务 , 因为服务肯定的包含对数据的读取、写入、更新、删除 , 可是由于一致性(C)的要求 , 系统中所有的节点数据都要保持一致 , 因为分区错误发生 , 节点的数据同步肯定无法进行 , 数据副本的一致性就无法保证 , 那就不能像对外提供服务 。那这样CA就相互矛盾 , 系统无法保证可用性(A)和一致性(C) , 系统自然是不能使用了 , 也就是说没有选择CA的分布式系统 , 而且这分区容忍性(P)必须要考虑!而且 , 不是一个系统选择了可用性(A)或者一致性(C) , 可以是其中的模块选择了可用性(A)和一致性(C)
Zookeeper常常有人用它作为dubbo的注册中心 , Eureka作为Spring Cloud体系中的注册中心 , 其实对于注册中心角色来说 , 我觉得Eureka比Zookeeper更适合!
还有一点这里我说一下 , 其实大部分情况下分布式系统是没有问题的 , C和A两个指标都是同时满足的 , 只是在分区问题发生的情况下 , 才需要我们考虑到底是选择C还是A 。
前文说到解决单点故障的问题 , 我们引入了集群 。在分布式系统中我们为了提高系统的可用性 , 也是不可避免的使用副本的机制 , 引入了副本则就需要同步数据到不同的副本 , 从而引发了副本一致性的问题 。就如前面展示的“分布式架构图”中 , 会员、订单和产品服务都是独立部署且分别使用不同的数据库 , 每个服务内部又是使用数据库集群 , 数据在服务与服务之间、在某个服务的数据库集群中间等等的流转、同步 , 这些过程都是有网络、时间消耗的 , 一个数据从最开始的产生到它应该到的地方不会瞬时完成 , 而CAP理论是基于瞬时 , 在同一时刻任意节点都保持着最新的数据副本 , 它是忽略网络延迟、节点处理数据的速度的 , 这个在目前的技术下是不可能做到的 , 从这个角度来看 , CAP理论实在是乐观主义了 。


推荐阅读