CAP理论
CAP定理指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)这三个基本需求,最多只能同时满足其中的2个
可用性(Availability)
系统提供的服务必须一致处于可用的状态,每次请求都能获取到非错的响应
在大型分布式系统中有一个大问题,那就是一些很罕见的问题会被放大。
对于分布式系统的容错,有很多不同的概念可以表述,有一个共同的思想就是可用性。某些系统经过精心的设计,这样在特定的错误类型下,仍然可以正常运行
另一个容错特性是自我可恢复性,为了实现这个特性,有很多工具,其中最重要的两个:
- 一个是非易失存储:比方说硬盘,闪存,SSD之类的。更新非易失存储是代价很高的操作,所以相应的出现了很多非易失存储的管理工具,聪明的做法是避免频繁写入非易失存储
- 另一个工具是复制:不过管理复制的多副本有些棘手
一致性(Consistency)
一致性就是用来定义操作行为的概念,在一个分布式系统中,由于复制或者缓存,数据可能存在于多个副本当中,数据需要在多个副本之间能够保持一致的特性
强一致性:如果想要做到强一致性,分布式系统的各个组件需要做大量的通信
弱一致性:比方说在一个k-v数据库中,弱一致性指的是可以保存get得到的是put写入的最新的数据
分区容错性(Partition tolerance)
分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障
什么是分区?
在分布式系统中,不同的节点分布在不同的子网络中,由于一些特殊的原因,这些子节点之间出现了网络不通的状态,但他们的内部子网络是正常的。从而导致了整个系统的环境被切分成了若干个孤立的区域,这就是分区。
CAP原则权衡
我们在CAP理论中是无法同时满足CAP的,那要丢弃哪一个呢?
CA without P
如果不要求分区,则可用性和一致性是可以保证的。但其实分布不是想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各字系统依然保持CA
CP without A
如果不要求可用性,相当于每个请求都要在Server之间强一致,而分区会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式
AP without C
要高可用并允许分区,则需放弃一致性,一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在很多的NoSQL都属于这类
不是所谓的“3 选 2”
大部分人解释这一定律时,常常简单的表述为:“一致性、可用性、分区容忍性三者你只能同时达到其中两个,不可能同时达到”。实际上这是一个非常具有误导性质的说法,而且在 CAP 理论诞生 12 年之后,CAP 之父也在 2012 年重写了之前的论文。
当发生网络分区的时候,如果我们要继续服务,那么强一致性和可用性只能 2 选 1。也就是说当网络分区之后 P 是前提,决定了 P 之后才有 C 和 A 的选择。也就是说分区容错性(Partition tolerance)我们是必须要实现的。
简而言之就是:CAP 理论中分区容错性 P 是一定要满足的,在此基础上,只能满足可用性 A 或者一致性 C。
因此,分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。
总结
在微服务的构建中,永远都逃离不了CAP理论,因为网络永远不稳定,硬件总会老化,软件会可能出现bug,所以分区容错性在微服务中是躲不过的命题,可以这么说,只要是分布式,只要是集群都面临着AP或者CP的选择,但你很贪心的时候,既要一致性又要可用性,那只能对一致性作出一点妥协,也就是引入了BASE理论,在业务允许的情况下实现最终一致性。