概述
如何实现如下要求的分布式系统?
- 既要提升系统的可用性。
- 又要保证数据一致,实时可见。
- 还要保障系统的集群容错能力。
实际这些要求就是无法实现的,因为它违背了CAP原则。
CAP原则又被称作布鲁尔定理(Brewer's theorem),指的是在一个分布式系统中,最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项,即不可能同时满足CAP三项特性,如下图所示。
image.png比如上海的静态化管理阶段也是满足这个原理的
- 人停工企业停产(牺牲可用性)
- 全城全面核酸,统一采用核酸码平台,实时统筹管理数据(保证数据的一致性)
- 人被限制在小区内活动、交换物资,小区间封闭(分区容错)
一致性(Consistency)
一致性是指,一旦客户端将值写入任何一台服务器并获得响应,那么之后任意客户端从任意服务器读取的都是刚刚新写入的数据。如下图所示:
image.png一致性保证了:不管向哪台服务器写入数据,其他的服务器能实时同步这个新数据,之后不管从哪个服务器读取数据得到的都是最新的数据。如果同步有问题,那么首先解决同步的问题,挂起请求等待同步完成后才响应,那么可能是延迟很久才得到了正确结果,也可能是请求异常或者结果异常。如下图所示:
image.png
可用性(Availability)
可用性是指,向任意未崩溃的服务器发送请求,总能保证收到响应数据(允许不是最新数据),如下图所示:
image.png分区容错性(Partition tolerance)
分区的概念是:在分布式系统中,不同的节点分布在不同的子网络中,由于一些特殊的原因,这些子节点之间出现了网络不通的状态,但他们的内部子网络是正常的。从而导致了整个系统的环境被切分成了若干个孤立的区域。这就是分区。
分布式系统在遇到任何网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。比如两个服务器,给对方任何消息都可以失败;也就是说会因为各种意外情况,导致无法成功进行数据同步,分布式系统要能容忍这种情况。
image.pngCAP的取舍
传统的单机系统满足CA,而没有P。在分布式系统中,首先必须要满足P(分布式系统,因为是多节点的,一定要考虑part failure),所以C,A需要根据具体场景进行取舍。
通过一个示例来梳理,如整个系统由服务节点A、B组成,之间通过网络通信,当节点 A 进行更新数据操作的时候,需要同时更新节点 B 的数据(这个数据复制的过程是一个原子操作)。
image.png上图这个系统怎么满足 CAP 呢?通过反证法来梳理: 假设可以同时满足一致性、可用性、分区容错这三个特性,由于满足分区容错,可以切断 A、B两个服务节点间的通信
- A、B连接断开后,就出现了网络分区,因为节点 A、B无法通信,一致性就无法满足。
- 如果强行满足一致性,就必须停止提供服务,修复A、B的通信故障,从而放弃可用性。
总结来看:
- 若要保证一致性:则必须进行节点间数据复制,复制期间数据锁定,导致期间的读取失败或超时,破坏了可用性;
- 若要保证可用性:则不允许节点间数据复制时被锁定,这又破坏了一致性。
组合 | 结果 |
---|---|
AC | 单机应用 满足一致性和可用性,没有分区容错 |
CP | 满足一致性和分区容错性,也就是说,要放弃可用性。当系统被分区,为了保证原子性,必须放弃可用性,让服务停用。 |
AP | 满足可用性和分区容错性,当出现分区,同时为了保证可用性,即使数据未同步,也必须让节点继续对外服务,这样必然导致失去数据的一致性 |
一致性的取舍
对一致性的要求在不同的场景下有差异,如:
- 强一致性
任何时刻,任何用户能读取到最近一次成功更新的数据。 - 弱一致性
用户无法在确定时间内读到最新更新的值 - 最终一致性
是弱一致性的特殊形式,用户只能读到某次更新后的值,但系统保证在过了不一致的时间窗口后数据将最终达到完全一致的状态,后续的读取一定一致。
分布式业务系统实现中,通常会选择牺牲一致性来换取可用性。所谓的牺牲一致性 实际是 牺牲的是【强一致性】中的【强】,把强转弱。强一致性:数据复制对外部操作者来说是同步的;弱一致性:数据复制对外部操作者来说的异步的。
网友评论