分布式系统核心理论:CAP 原则与 BASE 理论深度解读
CAP 原则:分布式系统的三大难题
在分布式系统中,CAP 原则如同一座难以逾越的山脉,它明确指出,Consistency(一致性)、Availability(可用性)和 Partition tolerance(分区容错性)这三大需求,我们最多只能同时满足其中的两个。这三大需求究竟是什么?又为何如此重要?让我们一探究竟。
一致性(Consistency):想象一下,你在多个城市的银行都有账户,当你在 A 城市的银行查询余额时,希望得到的是所有账户的准确总和,这就是一致性。在分布式系统中,一致性要求访问所有节点得到的数据都是一样的,确保数据的准确无误。
可用性(Availability):当你在 B 城市的银行办理业务时,你希望银行系统能够随时响应你的请求,无论是查询余额还是进行转账,这就是可用性。在分布式系统中,可用性意味着所有节点都保持高可用性,能够及时响应用户的请求。
分区容错性(Partiton tolerence):由于网络的不可靠性,分布式系统中的节点之间可能会出现无法通信的情况,就像 C 城市的银行系统与其他城市的银行系统突然失去了联系。在这种情况下,分区容错性要求系统仍然能够继续正常服务,不会因为部分节点的故障而导致整个系统崩溃。
分区的概念
在分布式系统中,不同的节点分布在不同的子网络中,由于一些特殊的原因,这些子节点之间出现了网络不通的状态,但他们的内部子网络是正常的。从而导致了整个系统的环境被切分成了若干个孤立的区域,这就是分区。
C(一致性) 和 A(可用性) 的矛盾
一致性和可用性,为什么不可能同时成立?答案很简单,因为可能通信失败(即出现分区容错)。
系统设计时只能选择一个目标。如果追求一致性,那么无法保证所有节点的可用性;如果追求所有节点的可用性,那就没法做到一致性。
CAP 原则的权衡:选择与取舍
在实际的分布式系统设计中,我们往往需要在一致性、可用性和分区容错性之间进行权衡。当网络分区发生时,如果我们选择继续服务,那么强一致性和可用性只能二选一。这是因为分区容错性(P)是前提,我们必须先保证系统的分区容错性,才能考虑一致性和可用性的问题。
CA 架构:强一致性和可用性,但失去了扩展性
CA without P:如果我们选择 CA 架构,即不要求分区容错性(P),那么我们可以保证强一致性和可用性。然而,这种选择意味着我们放弃了系统的扩展性,分布式节点受限,无法部署子节点,这与分布式系统设计的初衷相违背。传统的关系型数据库,如 Oracle、MySQL,就是典型的 CA 架构。
CP 架构:强一致性,但牺牲了可用性
CP without A:如果我们选择 CP 架构,即不要求可用性(A),那么我们可以保证强一致性和分区容错性(P)。在这种架构下,每个请求都需要在服务器之间保持强一致,而分区会导致同步时间无限延长,一旦发生网络故障或者消息丢失等情况,用户只能等待所有数据全部一致后才能访问系统。这种架构适用于对数据一致性要求极高的场景,如分布式数据库 Redis、HBase 等。
AP 架构:高可用性,但牺牲了一致性
AP wihtout C:如果我们选择 AP 架构,即不要求一致性(C),那么我们可以保证高可用性和分区容错性(P)。在这种架构下,一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,这会导致全局数据的不一致性。这种架构适用于对可用性要求高,但可以容忍一定程度数据不一致性的场景,如某米的抢购手机场景。
- No SQL:Coach DB
BASE 理论:分布式系统的一致性新思路
BASE
是 Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写。
BASE 理论是对 CAP 原则中一致性和可用性权衡的结果,它提出了一种新的思路,即使无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。
基本可用:允许部分损失,但系统仍可正常运行
基本可用是指分布式系统在出现不可预知故障时,允许损失部分可用性,但系统仍然可以正常运行。
例如,在线搜索引擎在部分机房发生断电或断网故障时,查询结果的响应时间可能会增加,但系统仍然可以返回查询结果。再如,电子商务网站在购物高峰时,为了保护系统稳定性,可能会引导部分消费者到降级页面,但系统仍然可以处理大部分订单。
软状态:允许数据存在中间状态
软状态(Soft state)是指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性。这意味着系统在不同节点的数据副本之间进行数据同步的过程可能存在延时,但最终数据会达到一致状态。
最终一致性:数据最终会达到一致状态
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到一个一致的状态。这并不需要系统实时保证数据的强一致性,而是允许数据在一段时间内是不一致的,但最终会达到一致状态。
例如,亚马逊首席技术官 Werner Vogels 在 2008 年发表的一篇文章中对最终一致性进行了详细介绍,他认为最终一致性是一种特殊的弱一致性,系统能够保证在没有其他新的更新操作的情况下,数据最终一定能够达到一致的状态。
BASE 理论的变种:满足不同业务需求
在实际工程实践中,最终一致性存在多种变种形式,以满足不同业务场景的需求。
因果一致性:
如果进程 A 在更新完某个数据项后通知了进程 B,那么进程 B 之后对该数据项的访问都应该能够获取到进程 A 更新后的最新值,并且如果进程 B 要对该数据项进行更新操作的话,务必基于进程 A 更新后的最新值,即不能发生丢失更新情况。
读己之所写:
进程 A 更新一个数据项之后,它自己总是能够访问到更新过的最新值,而不会看到旧值。这对于单个数据获取者而言,其读取到的数据一定不会比自己上次写入的值旧。
会话一致性:
系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。
单调读一致性:
如果一个进程从系统中读取出一个数据项的某个值后,那么系统对于该进程后续的任何数据访问都不应该返回更旧的值。
单调写一致性:
一个系统需要能够保证来自同一个进程的写操作被顺序地执行。
小结
总的来说,BASE 理论面向的是大型高可用可扩展的分布式系统,它与传统事务的 ACID 特性相反,完全不同于 ACID 的强一致性模型,而是提出通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。然而,在实际的分布式场景中,不同业务单元和组件对数据一致性的要求是不同的,因此在具体的分布式系统架构设计过程中,ACID 特性与 BASE 理论往往会结合在一起使用,以满足不同业务场景的需求。
扩展: 分布式系统的典型应用
分布式系统是一个非常广泛的概念,它最终要落实到解决实际问题上,不同的问题有不同的方法和架构。所有的开源软件都是以某个应用场景出现,而纯粹以“分布式”概念进行划分的比较少见。但如果以算法划分,到能分出几类:
- 以Leader选举为主的一类算法,比如paxos、viewstamp,就是现在zookeeper、Chuby等工具的主体
- 以分布式事务为主的一类主要是二段提交,这些分布式数据库管理器及数据库都支持
- 以若一致性为主的,主要代表是Cassandra的W、R、N可调节的一致性
- 以租赁机制为主的,主要是一些分布式锁的概念,目前还没有看到纯粹“分布式”锁的实现
- 以失败探测为主的,主要是Gossip和phi失败探测算法,当然也包括简单的心跳
- 以弱一致性、因果一致性、顺序一致性为主的,开源尚不多,但大都应用在Linkedin、Twitter、Facebook等公司内部
- 以异步解耦为主的,还有各类Queue
评论