参考大佬文章:分布式理论 —— CAP 定理、分布式CAP定理,为什么不能同时满足三个特性?
一、什么是 CAP 定理
CAP 理论表明,一个分布式系统不可能同时满足一致性(Consistency),可用性(Availability)和分区容错性(Partition tolerance)这三个基本需求,最多只能同时满足其中的2个。
高可用:就是当一台或者多台服务器宕机的时候,系统整体和服务依然正常可用。
什么是分区?
在分布式系统中,不同的节点分布在不同的子网络中,由于一些特殊的原因,这些子节点之间出现了网络不通的状态,但它们的内部子网络是正常的,从而导致了整个系统的环境被切分成了若干个孤立的区域,这就是分区。(分区:就是分布式集群中的某些节点之间互相访问不通,分隔成了独立的几个节点)
二、为什么只能 3 选 2?
能不能同时满足这三个条件?假设有一个系统如下:
整个系统由两个节点配合组成,之间通过网络通信,当节点 A 进行更新数据库操作的时候,需要同时更新节点 B 的数据库(这是一个原子的操作)。
上面这个系统怎么满足 CAP 呢?
C:当节点 A 更新的时候,节点 B 也要更新。
A:必须保证两个节点都是可用的。
P:当节点 A、B 出现了网络分区,必须保证对外可用。
可见,根本完成不了,只要出现了网络分区,A 就无法满足,因为节点 A 根本连接不上节点 B。如果强行满足 C 一致性,就必须停止A对外的服务,直到AB之间完成数据同步(从而放弃可用性 A)。
所以,最多满足两个条件:
1. CA:放弃P(分区容错性),也就是单体服务,不做分区(多个服务)。
但放弃P的同时也就意味着放弃了系统的扩展性,也就是分布式节点受限,没办法部署子节点,这是违背分布式系统设计的初衷的。
2. CP:放弃A(可用性),当分布式服务集群中,某一个服务A挂了,此时为了保证C的一致性,需要停止其余对外服务,直到挂了的服务A恢复并完成数据同步后,再继续整体对外提供服务。
比如:一旦发生网络故障或者消息丢失等情况,就要牺牲用户的体验,等待所有数据全部一致了之后再让用户访问系统。
3. AP:为了高可用而放弃C(一致性),同时满足A和P(同时存在多个服务),可能会出现某些服务之间的数据不一致的情况。
举例:典型的应用就如某米的抢购手机场景,可能前几秒你浏览商品的时候页面提示是有库存的,当你选择完商品准备下单的时候,系统提示你下单失败,商品已售完。这其实就是先在 A(可用性)方面保证系统可以正常的服务,然后在数据的一致性方面做了些牺牲,虽然多少会影响一些用户体验,但也不至于造成用户购物流程的严重阻塞。
三、能不能解决 3 选 2 的问题?
难道真的没有办法解决这个问题吗?CAP 理论已经提出了 13 年,也许可以做些改变。仔细想想,分区是百分之百出现的吗?如果不出现分区(只用单体服务),那么就能够同时满足 CAP。如果出现了分区,可以根据策略进行调整。比如 C 不必使用那么强的一致性,可以先将数据存起来,稍后再更新,实现所谓的 “最终一致性”。
四、总结
现如今,对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,节点只会越来越多,所以节点故障、网络故障是常态,因此分区容错性也就成为了一个分布式系统必然要面对的问题。那么就只能在C和A之间进行取舍。但对于传统的项目就可能有所不同,拿银行的转账系统来说,涉及到金钱的对于数据一致性不能做出一丝的让步,C必须保证,出现网络故障的话,宁可停止服务,可以在A和P之间做取舍。
总而言之,没有最好的策略,好的系统应该是根据业务场景来进行架构设计的,只有适合的才是最好的。