在足球比赛里,一个球员在一场比赛中进三个球,称之为帽子戏法(Hat-trick)。在分布式数据系统中,也有一个帽子原理(CAP Theorem),不过此帽子非彼帽子。CAP原理中,有三个要素:html
CAP原理指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。所以在进行分布式架构设计时,必须作出取舍。而对于分布式数据系统,分区容忍性是基本要求,不然就失去了价值。所以设计分布式数据系统,就是在一致性和可用性之间取一个平衡。对于大多数web应用,其实并不须要强一致性,所以牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向。java
固然,牺牲一致性,并非彻底无论数据的一致性,不然数据是混乱的,那么系统可用性再高分布式再好也没有了价值。牺牲一致性,只是再也不要求关系型数据库中的强一致性,而是只要系统能达到最终一致性便可,考虑到客户体验,这个最终一致的时间窗口,要尽量的对用户透明,也就是须要保障“用户感知到的一致性”。一般是经过数据的多份异步复制来实现系统的高可用和数据的最终一致性的,“用户感知到的一致性”的时间窗口则取决于数据复制到一致状态的时间。web
最终一致性(eventually consistent)数据库
对于一致性,能够分为从客户端和服务端两个不一样的视角。从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。一致性是由于有并发读写才有的问题,所以在理解一致性的问题时,必定要注意结合考虑并发读写的场景。编程
从客户端角度,多进程并发访问时,更新过的数据在不一样进程如何获取的不一样策略,决定了不一样的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。若是能容忍后续的部分或者所有访问不到,则是弱一致性。若是通过一段时间后要求能访问到更新后的数据,则是最终一致性。架构
最终一致性根据更新数据后各进程访问到数据的时间和方式的不一样,又能够区分为:并发
- 因果一致性。若是进程A通知进程B它已更新了一个数据项,那么进程B的后续访问将返回更新后的值,且一次写入将保证取代前一次写入。与进程A无因果关系的进程C的访问遵照通常的最终一致性规则。
- “读己之所写(read-your-writes)”一致性。当进程A本身更新一个数据项以后,它老是访问到更新过的值,毫不会看到旧值。这是因果一致性模型的一个特例。
- 会话(Session)一致性。这是上一个模型的实用版本,它把访问存储系统的进程放到会话的上下文中。只要会话还存在,系统就保证“读己之所写”一致性。若是因为某些失败情形令会话终止,就要创建新的会话,并且系统的保证不会延续到新的会话。
- 单调(Monotonic)读一致性。若是进程已经看到过数据对象的某个值,那么任何后续访问都不会返回在那个值以前的值。
- 单调写一致性。系统保证来自同一个进程的写操做顺序执行。要是系统不能保证这种程度的一致性,就很是难以编程了。
上述最终一致性的不一样方式能够进行组合,例如单调读一致性和读己之所写一致性就能够组合实现。而且从实践的角度来看,这二者的组合,读取本身更新的数据,和一旦读取到最新的版本不会再读取旧版本,对于此架构上的程序开发来讲,会少不少额外的烦恼。异步
从服务端角度,如何尽快将更新后的数据分布到整个系统,下降达到最终一致性的时间窗口,是提升系统的可用度和用户体验很是重要的方面。对于分布式数据系统:分布式
若是W+R>N,写的节点和读的节点重叠,则是强一致性。例如对于典型的一主一备同步复制的关系型数据库,N=2,W=2,R=1,则无论读的是主库仍是备库的数据,都是一致的。性能
若是W+R<=N,则是弱一致性。例如对于一主一备异步复制的关系型数据库,N=2,W=1,R=1,则若是读的是备库,就可能没法读取主库已经更新过的数据,因此是弱一致性。
对于分布式系统,为了保证高可用性,通常设置N>=3。不一样的N,W,R组合,是在可用性和一致性之间取一个平衡,以适应不一样的应用场景。
转自:http://www.blogjava.net/hello-yun/archive/2012/04/27/376744.html
参见:http://www.infoq.com/cn/news/2008/01/consistency-vs-availability