海量存储的一致性和高可用

海量存储的一致性和高可用

为了更好的描述一致性,我们通过以下的场景来进行,这个场景中包括三个组成部分:

  • 存储系统
存储系统可以理解为一个黑盒子,它为我们提供了可用性和持久性的保证。
  • Process A
ProcessA主要实现从存储系统write和read操作
  • Process B 和ProcessC
ProcessB和C是独立于A,并且B和C也相互独立的,它们同时也实现对存储系统的write和read操作。

下面以上面的场景来描述下不同程度的一致性:

  • CA 强一致性
强一致性(即时一致性) 假如A先写入了一个值到存储系统,存储系统保证后续A,B,C的读取操作都将返回最新值
  • CP 弱一致性
假如A先写入了一个值到存储系统,存储系统不能保证后续A,B,C的读取操作能读取到最新值。此种情况下有一个“不一致性窗口”的概念,它特指从A写入值,到后续操作A,B,C读取到最新值这一段时间。
  • AP 最终一致性

最终一致性是弱一致性的一种特例。假如A首先write了一个值 到存储系统,存储系统保证如果在A,B,C后续读取之前没有其它写操作更新同样的值的话,最终所有的读取操作都会读取到最A写入的最新值。此种情况下,如 果没有失败发生的话,“不一致性窗口”的大小依赖于以下的几个因素:交互延迟,系统的负载,以及复制技术中replica的个数(这个可以理解为 master/salve模式中,salve的个数),最终一致性方面最出名的系统可以说是DNS系统,当更新一个域名的IP以后,根据配置策略以及缓存 控制策略的不同,最终所有的客户都会看到最新的值。

c是一致性,就是无论何时何人的读取的信息都是一样的,a是高可用,就是无论何时都要保证系统是可用的;p就是容忍集群中有个别的节点失去联系,不是光从一致性上考虑的。

Jack's Blog 2015-01-25 33 阅读
 

关于数据存储中著名的 CAP 定理, 很多业界人士都给出了自己的解决方案. 美其名曰:"打败CAP定理", 总结如下:

最终一致性(Cassandra的做法):

对于分布式数据系统:

  • N — 数据复制的份数

  • W — 更新数据是需要保证写完成的节点数

  • R — 读取数据的时候需要读取的节点数

如果W+R>N,写的节点和读的节点重叠,则是强一致性。例如对于典型的一主一备同步复制的关系型数据库,N=2,W=2,R=1,则不管读的是主库还是备库的数据,都是一致的。

如果W+R<=N,则是弱一致性。例如对于一主一备异步复制的关系型数据库,N=2,W=1,R=1,则如果读的是备库,就可能无法读取主库已经更新过的数据,所以是弱一致性。

对于分布式系统,为了保证高可用性,一般设置N>=3。不同的N,W,R组合,是在可用性和一致性之间取一个平衡,以适应不同的应用场景。

如果N=W,R=1,任何一个写节点失效,都会导致写失败,因此可用性会降低,但是由于数据分布的N个节点是同步写入的,因此可以保证强一致性。

如果N=R,W=1,只需要一个节点写入成功即可,写性能和可用性都比较高。但是读取其他节点的进程可能不能获取更新后的数据,因此是弱一致性。这种情况下,如果W<(N+1)/2,并且写入的节点不重叠的话,则会存在写冲突

Storm的作者的建议:

将实时数据和离线数据进行架构整合, 数据的一致性交由批处理的离线数据负责, Storm产生的实时数据则保证可用性 架构图

相关 Blog

关于NOSQL的CAP分类:

CAP分类图

关注一致性和可用性的 (CA)

这些数据库对于分区容忍性方面比较不感冒,主要采用复制(Replication)这种方式来保证数据的安全性,常见的CA系统有:

  1. 传统关系型数据库,比如Postgres和MySQL等(Relational) ;
  2. Vertica (Column-oriented) ;
  3. Aster Data (Relational) ;
  4. Greenplum (Relational) ;

关注一致性和分区容忍性的(CP)

这种系统将数据分布在多个网络分区的节点上,并保证这些数据的一致性,但是对于可用性的支持方面有问题,比如当集群出现问题的话,节点有可能因无法确保数据是一致性的而拒绝提供服务,主要的CP系统有: 1. BigTable (Column-oriented) ; 2. Hypertable (Column-oriented); 3. HBase (Column-oriented) ; 4. MongoDB (Document) ; 5. Terrastore (Document) ; 6. Redis (Key-value) ; 7. Scalaris (Key-value) ; 8. MemcacheDB (Key-value) ; 9. Berkeley DB (Key-value) ;

关于可用性和分区容忍性的(AP)

这类系统主要以实现"最终一致性(Eventual Consistency)"来确保可用性和分区容忍性,AP的系统有:

  1. Dynamo (Key-value);
  2. Voldemort (Key-value) ;
  3. Tokyo Cabinet (Key-value) ;
  4. KAI (Key-value) ;
  5. Cassandra (Column-oriented) ;
  6. CouchDB (Document-oriented) ;
  7. SimpleDB (Document-oriented) ;
  8. Riak (Document-oriented) ;

关于2pc的一致性和脑裂问题:

A prepare --> B commit --> A commit 

这是最原始的二阶段提交, 但是 如果B的反馈未知 , 那么整个集群则处于危险状况

  1. 一致性上就出现了问题,无反馈的情况下,无法区分成功还是失败了,于是最安全和保险的方式,就是等着。。。没错,你没看错,就是死等。等到B给个反馈。。。这种在可用性上基本上是0分了。。无论你有多少机器,死等总不是个办法

  2. A得不到B的反馈,又为了保证自己的可用性,唯一的选择就只好像【P A ->C B(b机器挂掉), 这里面所提到的方法一样:等待一段时间,超时以后,认为B机器挂掉了。于是自己继续接收新的请求,而不再尝试同步给B。又因为可用性指标是如此重要,所以 这基本成为了在这种情况下的必然选择,然而,这个选择会带来更大的问题,左脑和右脑被分开了!

碰到问题,就要去解决,所以,针对一致性问题上的那个“死等”的萌呆属性,有人提出了三段提交协议,使用增加的一段提交来减少这种死等的情况。不过3PC 基本上没有人在用,因为有其他协议可以做到更多的特性的同时又解决了死等的问题,所以3pc我们在这里就不表了。3pc是无法解决脑裂问题的,所以更多的 人把3pc当做发展过程中的一颗路旁的小石头。。

而针对脑裂,最简单的解决问题的方法,就是引入第三视点,observer。

既然两个人之间,直接通过网络无法区分出对方是不是挂掉了,那么,放另外一台机器在第三个机房,如果真的碰到无响应的时候,就去问问observer:对方活着没有啊?就可以防止脑裂问题了。但这种方法是无法解决一致性问题中的死等问题的。。。

所以,最容易想到的方式就是,3pc+observer,完美解决双机一致性和安全性问题。

原文地址:https://www.cnblogs.com/SZLLQ2000/p/5231376.html