CAP、ACID、BASE理论及NWR实践策略详解

一、分布式领域CAP理论,
Consistency(一致性), 保证获得的都是完成状态的数据,不然直接失败。

Availability(可用性), 在容忍的响应时间内,每一个操做老是可以返回,不会出现所谓in_flight IO,老是能及时响应。

Partition tolerance(分区容忍性) 可以保证系统是分区的。(原文是:No set of failures less than total network failure is allowed to cause the system to respond incorrectly),比较难理解,简单的解释一下这是个反证,除非整个分布式系统所在的网络都挂掉,不然只要还有分区就能给出正确响应。


定理:任何分布式系统只可同时知足二点,无法三者兼顾。
注意:架构师不要将精力浪费在如何设计能知足三者的完美分布式系统,而是应该进行取舍。


二、关系型数据库ACID模型:
关系数据库的ACID模型拥有 高一致性 + 可用性 可是很难知足分区容忍性:
Atomicity 原子性:一个事务中全部操做都必须所有完成,要么所有不完成。
Consistency 一致性. 在事务开始或结束时,数据库应该在一致状态。
Isolation 隔离性. 事务将假定只有它本身在操做数据库,彼此不知晓。
Durability 持久性. 一旦事务完成,就不能返回。
跨数据库事务:2PC (two-phase commit), 2PC is the anti-scalability pattern (Pat Helland) 是反可伸缩模式的,JavaEE中的JTA事务能够支持2PC。由于2PC是反模式,尽可能不要使用2PC,使用BASE来回避。


3. BASE理论

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

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

基本可用(Basically Available)
基本可用是指分布式系统在出现故障的时候,容许损失部分可用性,即保证核心可用。

电商大促时,为了应对访问量激增,部分用户可能会被引导到降级页面,服务层也可能只提供降级服务。这就是损失部分可用性的体现。 数据库

 软状态( Soft State)

软状态是指容许系统存在中间状态,而该中间状态不会影响系统总体可用性。分布式存储中通常一份数据至少会有三个副本,容许不一样节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。 swift

 最终一致性( Eventual Consistency)
最终一致性是指系统中的全部数据副本通过必定时间后,最终可以达到一致的状态。弱一致性和强一致性相反,最终一致性是弱一致性的一种特殊状况。

4. ACID和BASE的区别与联系

ACID是传统数据库经常使用的设计理念,追求强一致性模型。BASE支持的是大型分布式系统,提出经过牺牲强一致性得到高可用性。 缓存

ACID和BASE表明了两种截然相反的设计哲学 网络

在分布式系统设计的场景中,系统组件对一致性要求是不一样的,所以ACID和BASE又会结合使用。 架构


BASE思想主要强调基本的可用性,若是你须要High 可用性,也就是纯粹的高性能,那么就要以一致性或分区容忍性为牺牲,BASE思想的方案在性能上仍是有潜力可挖的。

如今NoSQL
运动丰富了拓展了BASE思想,可按照具体状况定制特别方案,好比忽视一致性,得到高可用性等等,NOSQL应该有下面两个流派:
1. Key-Value存储,如Amaze Dynamo等,可根据CAP三原则灵活选择不一样倾向的数据库产品。
2. 领域模型 + 分布式缓存 + 存储 (Qi4j和NoSQL运动),可根据CAP三原则结合本身项目定制灵活的分布式方案,难度高。

这二者共同点:都是关系数据库SQL之外的可选方案,逻辑随着数据分布,任何模型均可以本身持久化,将数据处理和数据存储分离,将读和写分离,存储能够是异步或同步,取决于对一致性的要求程度。

不一样点:NOSQL之类的Key-Value存储产品是和关系数据库头碰头的产品BOX,能够适合非Java如PHP RUBY等领域,是一种能够拿来就用的产品,而领域模型 + 分布式缓存 + 存储是一种复杂的架构解决方案,不是产品,但这种方式更灵活,更应该是架构师必须掌握的。

五、NWR是CAP理论的一个具体实践性的取舍策略: 并发


  Amazon写了个论文,描述了一下若是取舍的具体策略,具体到副本数怎么设定,这就是NWR。 less


  N = 副本数 异步

  W = 一次成功的写操做必须完成的写副本数

  R = 一次成功的读操做须要读的副本数(是的,随便读一个副本是不行的,你必须读到必定数量的副本,再相互比较取最新的数据)


策略来讲就有具体的公式可供运算,有两个:

 

  W > N/2

  W + R > N 


咱们结合Swift的设定,N=3,W=2,R=2(or 1),来看看这两个公式是什么意义。


分布式系统一般用来处理大并发请求的应用,不少请求你们同时来,有一堆在读,也有一堆想写。

假设有一个数据拥有三副本,每一个副本已经同步好,原来的值都是A


咱们看看若是不须要知足公式让W小于3/2,也就是W=1的状况下会出现什么问题,W=1,意味着每一个写的请求只要写完一个副本便可成功返回。


假设两个进程同时来更新这份数据,进程W1要把值改写成C,进程W2要把值改写成B,那就有可能出现下图的情形,两个进程各拿到一个副本改写,都认为本身的写操做是成功的,结果却留给系统三个不一样的副本,这样就出现数据副本不一致的问题。

Swift里的CAP理论和NWR策略应用

  因此公式W> N/2, 实际上变成了一个写的锁,意味着只有写了过半数副本的才算写成功,拿不到的就返回失败,解决了竞争的问题。以下图,W1的会话成功,W2的会话就返回失败。

Swift里的CAP理论和NWR策略应用

  W> N/2,同时意味着不须要把全部的副本都写完,未完成的留给系统本身后台慢慢同步,那这个时候问题就来了,一个新的会话过来读数据的时候,分配到的副本有多是没来得及更新的。这时候R1读回去的就是过期的数据B,而非最新的数据C

Swift里的CAP理论和NWR策略应用

 第2个公式变形下就是R> N-W,R=2就避免正好倒霉读到没更新的那一个。这样读回去C和B两个数据,再比较后取最新的C。因此W+R> N 可以保证每一个读的请求至少读到一份最新的数据,

Swift里的CAP理论和NWR策略应用 


    因此你也许已经琢磨出来,这两个公式更增强调一致性,在可用性上是有所保留的。


固然NWR还可能取其余值,不一样的取值表明了不一样的倾向。若是设定N=3, W=3, R=1,那么强调的是一致性,写数据的时候必定要把全部副本都刷新,杜绝中间状态,这样一致性获得很好保证;若是N=3, W=1, R=1,那强调的是可用性,这种状况下一致性是被牺牲掉了,因此上面两个保证一致性的公式在这种状况下就再也不适用。之因此可用性提升是由于读和写都放低了要求,只要完成一个副本便可,这样完成时间下降,响应速度是更快的。


N=3, W=2, R=2是一种折中的策略。其实Amazon的Dynamo就是采用的这个参数,听说Swift是照搬S3的。 

  因此回到Swift的副本设定来看,swift的NWR值是可调的,有两种配置,一种是标准的N3W2R2,可是实际上你也可使用N3W2R1,这个更实用点。在这种配置下,虽然一个数据拥有三副本,可是容错上读写是不同的。网络断线,硬盘故障等意外形成一个副本失效时, 系统仍然可读可写,但两个副本失效时,受影响的这部分数据系统就变成只读,没法再写了。


CAP理论和NWR策略在大规模系统下是比较合理的,除了被用来设计分布式存储以外,也用来设计分布式数据库,好比很热的NOSQL。另外,这个理论问世已经不短的时间,也常常看到有人发文要挑战他,也有一些吐槽等等,那个是另外的话题,这里就再也不继续了。


六、总结NWR:

R>N/2:表示一次读操做成功,必须是完成超过半数以上的副本读操做(否则有可能读到不一致数据或者出现问题无法根据票数多来进行选举)

R>N-W:表示一次成功的读操做,至少要完成超过全部副本数N减去全部写成功W份数的差值。这样即能保证每一个读请求至少可以读到一份最新数据。


N=3,W=3,R=1:总共副本数为3,强调了写的强一致性,写数据的时候必定要把全部副本刷新才能算写成功,杜绝中间状态,这样一致性达到了很好的保证。

N=3,W=1,R=1:总共副本数为3,这样一致性牺牲了,由于读写都放低了要求,因此提升了系统可用性。

swift及Amazon采用的默认策略:

N=3, W=2, R=2:这样保证了每次读写必须完成半数以上副本才能算成功,算是折中方案。

相关文章
相关标签/搜索