分布式系统中的FLP不可能原理、CAP理论与BASE理论(顺带提一下ACID)

分布式系统是由多个不同的服务节点组成,节点与节点之间通过消息传递进行通信和协调。根据消息传递的不同,分布式系统的运行模型可以分为异步模型系统 和同步模型系统。本文首先将介绍同步通信与异步通信的概念,然后在此基础上,介绍最小化异步模型系统中的FLP理论。接着,会介绍事务的ACID属性与分布式系统中的CAP理论。最后,会分析ACID原则和BASE理论之间的特点,比较两者之间的不同。全文将按照如下结构展开:
这里写图片描述

一、同步与异步

同步和异步关注的是消息通信机制

  • 同步

同步是指系统中的各个节点的时钟误差存在上限;并且消息传递必须在一定时间内完成,否则认为失败;同时各个节点完成处理消息的时间是一定的。(学术语言解释

换句话说,所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。(工程语言解释

拿最经典的打电话举例。

你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下”,然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。

  • 异步

异步是指系统中各个节点可能存在较大的时钟差异,同时消息传输时间是任意长的,各节点对消息进行处理的时间也可能是任意长的。(学术语言解释

换句话说,所谓异步,调用在发出之后,这个调用就直接返回了,所以没有返回结果。当一个异步过程调用发出后,调用者不会立刻得到结果。而是在调用发出后,被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用。 (工程语言解释

拿最经典的打电话举例。

在异步通信机制中,你打电话问书店老板有没有《分布式系统》这本书,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

——-补:异步模型(asynchronous model)
模型(model)是对现实的抽象。异步(asynchronous)模型的主要特点是:

  1. 进程之间的通信基于消息(message)。消息的传输是可靠的,即消息可能延迟,可能乱序,但最终都会到达。
  2. 没有时钟(clock)可用,因此进程无法做出消息超时的判断。
  3. 进程的存活状态是无法检测的,即外部不能区分进程运行缓慢或是终止的情况;但是进程的运行是“诚实”的,没有“Byzantine Failures”。

二、FLP不可能原理

现实生活中的系统往往都是异步系统。因为系统中各个节点之间的延时,是否宕机等等都是不确定的。那么,在最小化异步模型系统中,是否存在一个可以解决一致性问题的确定性共识算法

由Fischer、Lynch和Patterson三位科学家于1985年发表的论文《Impossibility of Distributed Consensus with One Faulty Process》指出:在异步模型中,分布式系统中只要有一个进程不可用(失去响应或暂停),就可能无法达成整体的共识。(No completely asynchronous consensus protocol can tolerate even a single unannounced process death)。

以上结论被称为FLP不可能原理。该定理被认为是分布式系统中重要的原理之一。

此定理实际上想要告诉人们,不要浪费时间去为异步分布式系统设计在任意场景下都能实现共识的算法。

异步模型上面已经提到,那么介绍下什么是 共识(consensus)算法

什么样的算法才能称得上解决了共识问题呢?

(对于一个变量:)

  1. 所有可用的的进程最终都必须确定自己的取值。
  2. 所有的进程对于这个取值都必须达成一致。
  3. 这个取值必须是由某一个进程提出来的。

满足以上三个条件的算法,就可以称之为”共识算法”。

[跳过引理1证明]

引理2:存在一个bivalent的初始configuration。

定义:
configuration :实体组,一个状态组包括几个进程(实体)

初始configuration :已经确定的,不含有不确定进程的

bivalent:共识算法(比如少数服从多数)无法确定共识值

univalent:共识算法(比如少数服从多数)可以确定共识值,可细分为 k-valent

假设这样一个场景:

我们有一个共识算法是基于多数(majority)的,C0={0,0,0},C1={1,1,1}。那么C0到C1的变化可能是:

  C0  ->  Cx  ->  Cy  ->  C1
{0,0,0} {0,0,1} {1,0,1} {1,1,1}

Cx和Cy是相邻的,且Cx是0-valent,Cy是1-valent。

取valent发生变化的两个相邻的configuration,C0和C1;令p是那个状态不同的进程。我们的共识算法必须要容忍进程p不可用的情况(论文的标题暗示的大前提)。

用上面的例子,Cx和Cy,当p0不可用时,{?,0,1}究竟是0-valent还是1-valent呢?如果算作0-valent,那么Cy={1,0,1}在p0可用时是1-valent,在p0不可用时是0-valent,从而Cy是bivalent;如果{?,0,1} 算作1-valent,那么类似地Cx是bivalent。

于是我们导出了矛盾:在容忍一个进程不可用的前提下,假设不存在bivalent的初始configuration是不成立的。

[跳过引理3的证明]

FLP Impossibility

由引理2,我们知道当一个进程不可用时就可能导致一个bivalent的初始configuration。由引理3,我们知道从一个bivalent的configuration一定能达到另一个bivalent的configuration。因此这个循环可以一直进行下去,集群可能永远无法达成共识。

总结(非教科书式总结)

FLP论文从理论上证明了没有共识算法是一定正确的,能够容忍一个进程的不可用。但为什么仍然存在Paxos或Raft这样的共识算法呢?

首先,可能性的存在和实际发生的概率是独立的。现实中根据需要,我们可以接受一个在绝大多数情况下能达成共识的算法。

其次,最重要的是,FLP Impossibility是在异步模型上证明的;而异步模型并不完全适合我们的现实场景。回想异步模型的第二个特点:“没有时钟(clock)可用”,然而现实的系统中我们是可以做出“超时(timeout)”的判断的。例如Failure Detector的论文Unreliable Failure Detectors for Reliable Distributed Systems在异步模型中增加超时的条件,可以达到确定性的对某个进程的存活状态达成共识。

Paper Study: “Impossibility of Distributed Consensus with One Faulty Process” (FLP Impossibility)

三、CAP理论

2000年7月,加州大学伯克利分校的Eric Brewer教授在ACM PODC会议上提出CAP猜想。2年后,麻省理工学院的Seth Gilbert和Nancy Lynch从理论上证明了CAP。之后,CAP理论正式成为分布式计算领域的公认定理。

CAP理论概述

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

这里写图片描述

Consistency(数据一致性):

任何读请求都必须返回最新数据

对于一致性,可以分为从客户端和服务端两个不同的视角。

  • 客户端
    从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。

  • 服务端
    从服务端来看,则是更新如何分布到整个系统,以保证数据最终一致。

对于一致性,可以分为强/弱/最终一致性三类

从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。

  • 强一致性
    对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。

  • 弱一致性
    如果能容忍后续的部分或者全部访问不到,则是弱一致性。

  • 最终一致性
    如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。

最终一致性是弱一致性的一个特例,上课的时候老师的讲法是这样的

比如master下发一条记录到10个chunk,如果写到6个就再开一条操作。

如果涉及这条未完成记录,当读这条记录,同时读10个(隐含假设读不要花时间),投票法决定

Availability(服务可用性):”Reads and writes always succeed

所有读写请求都必须正常响应,可终止、不会一直等待

好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。可用性通常情况下可用性和分布式数据冗余,负载均衡等有着很大的关联。

Partition Tolerance(分区容忍性):“the system continues to operate despite arbitrary message loss or failure of part of the system

在网络分区的情况下,被分隔的节点仍能正常对外服务

即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性或可用性的服务。

CAP的证明

这里写图片描述

上图是我们证明CAP的基本场景,网络中有两个节点N1和N2,可以简单的理解N1和N2分别是两台计算机,他们之间网络可以连通,N1中有一个应用程序A,和一个数据库V,N2也有一个应用程序B2和一个数据库V。现在,A和B是分布式系统的两个部分,V是分布式系统的数据存储的两个子数据库。

在满足一致性的时候,N1和N2中的数据是一样的,V0=V0。在满足可用性的时候,用户不管是请求N1或者N2,都会得到立即响应。在满足分区容错性的情况下,N1和N2有任何一方宕机,或者网络不通的时候,都不会影响N1和N2彼此之间的正常运作。

这里写图片描述

上图是分布式系统正常运转的流程,用户向N1机器请求数据更新,程序A更新数据库Vo为V1,分布式系统将数据进行同步操作M,将V1同步的N2中V0,使得N2中的数据V0也更新为V1,N2中的数据再响应N2的请求。

这里,可以定义N1和N2的数据库V之间的数据是否一样为一致性;外部对N1和N2的请求响应为可用性;N1和N2之间的网络环境为分区容错性。

这是正常运作的场景,也是理想的场景,然而现实是残酷的,当错误发生的时候,一致性和可用性还有分区容错性,是否能同时满足,还是说要进行取舍呢?

作为一个分布式系统,它和单机系统的最大区别,就在于网络,现在假设一种极端情况,N1和N2之间的网络断开了,我们要支持这种网络异常,相当于要满足分区容错性,能不能同时满足一致性和响应性呢?还是说要对他们进行取舍。

这里写图片描述

假设在N1和N2之间网络断开的时候,有用户向N1发送数据更新请求,那N1中的数据V0将被更新为V1,由于网络是断开的,所以分布式系统同步操作M,所以N2中的数据依旧是V0;这个时候,有用户向N2发送数据读取请求,由于数据还没有进行同步,应用程序没办法立即给用户返回最新的数据V1,怎么办呢?

有二种选择,第一,牺牲数据一致性,响应旧的数据V0给用户;第二,牺牲可用性,阻塞等待,直到网络连接恢复,数据更新操作M完成之后,再给用户响应最新的数据V1。

这个过程,证明了要满足分区容错性的分布式系统,只能在一致性和可用性两者中,选择其中一个。

CAP权衡

通过CAP理论,我们知道无法同时满足一致性、可用性和分区容错性这三个特性,那要舍弃哪个呢?

CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。
CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。
AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。

对于多数大型互联网应用的场景,主机众多、部署分散,而且现在的集群规模越来越大,所以节点故障、网络故障是常态,而且要保证服务可用性达到N个9,即保证P和A,舍弃C(退而求其次保证最终一致性)。虽然某些地方会影响客户体验,但没达到造成用户流程的严重程度。

对于涉及到钱财这样不能有一丝让步的场景,C必须保证。网络发生故障宁可停止服务,这是保证CA,舍弃P。貌似这几年国内银行业发生了不下10起事故,但影响面不大,报道也不多,广大群众知道的少。还有一种是保证CP,舍弃A。例如网络故障事只读不写。

孰优孰略,没有定论,只能根据场景定夺,适合的才是最好的。

四、BASE理论

BASE理论是有eBay的架构师Dan Pritchett源于对大规模分布式系统的实践总结,在ACM上发表文章提出BASE理论,BASE理论是对CAP理论的延伸,核心思想是即使无法做到强一致性(Strong Consistency,CAP的一致性就是强一致性),但应用可以采用适合的方式达到最终一致性(Eventual Consitency)。

BASE理论的定义

BASE是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)。

  • 基本可用(Basically Available)
    基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。
    电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。

  • 软状态( Soft State)
    软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。
    分布式存储中一般一份数据至少会有三个副本,允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。

  • 最终一致性( Eventual Consistency)
    最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊情况。

BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。

ACID原则

ACID原则指的是:Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性),用了四种特性的缩写。

ACID也是一种比较出名的描述一致性的原则,通常出现在分布式数据库领域。具体来说,ACID原则描述了分布式数据库需要满足的一致性需求,同时允许付出可用性的代价。

ACID特征如下:

  • Atomicity:每次操作是原子的,要么成功,要么不执行;
  • Consistency:数据库的状态是一致的,无中间状态;
  • Isolation:各种操作彼此之间互相不影响;
  • Durability:状态的改变是持久的,不会失效。

ACID和BASE的区别与联系

ACID是传统数据库常用的设计理念,追求强一致性模型。

BASE支持的是大型分布式系统,牺牲掉对一致性的约束(但实现最终一致性),来换取一定的可用性。

ACID和BASE代表了两种截然相反的设计哲学。

在英文中,ACID和BASE分别是“酸”和“碱”,看似对立,实则是分别对CAP三特性的不同取舍。在分布式系统设计的场景中,系统组件对一致性要求是不同的,因此ACID和BASE又会结合使用。

猜你喜欢

转载自blog.csdn.net/jh_zhai/article/details/80265308