【分布式数据一致性二】Zookeeper数据读写一致性

不少文档说Zookeeper是强一致性保证,事实否则。关于一致性模型请参考http://bit1129.iteye.com/blog/2155336数据库

 


 Zookeeper的数据同步协议

Zookeeper采用称为Quorum Based Protocol的数据同步协议。假如Zookeeper集群有N台Zookeeper服务器(N一般取奇数,3台可以知足数据可靠性同时有很高读写性能,5台在数据可靠性和读写性能方面平衡最好),那么用户的一个写操做,首先同步到N/2 + 1台服务器上,而后返回给用户,提示用户写成功。基于Quorum Based Protocol的数据同步协议决定了Zookeeper可以支持什么强度的一致性编程

 

强一致性(Strong Consistency)

在分布式环境下,知足强一致性的数据储存基本不存在,它要求在更新一个节点的数据,须要同步更新全部的节点。这种同步策略出如今主从同步复制的数据库中。可是这种同步策略,对写性能的影响太大而不多见于实践。由于Zookeeper是同步写N/2+1个节点,还有N/2个节点没有同步更新,因此Zookeeper不是强一致性的。服务器

 

弱一致性

用户的数据更新操做,不保证后续的读操做可以读到更新后的值,可是最终会呈现一致性。牺牲一致性,并非彻底无论数据的一致性,不然数据是混乱的,那么系统可用性再高分布式再好也没有了价值。牺牲一致性,只是再也不要求关系型数据库中的强一致性,而是只要系统能达到最终一致性便可并发

 

CopyOnWriteArrayList是一个读写分离的并发ArrayList,它的遍历是弱一致性的,由于能够容忍并发修改,不会抛出ConcurrentModificationException,不像普通的集合,容许即时失败。分布式

 

最终一致性

最终一致性本质上和弱一致性是一回事,由于一个数据存储系统知足弱一致性可是不知足最终一致性,那么这个系统的数据就是不正确,一个数据不正确的系统是一个没法交付使用的系统。Zookeeper知足最终一致性,只要数据同步到Quorum以外的节点就会达到最终一致性。性能

 

因果一致性

Zookeeper是否知足因果一致性,须要看客户端的编程方式。spa

  • 不知足因果一致性的作法

1. A进程向Zookeeper的/z写入一个数据,成功返回线程

2. A进程通知B进程,A已经修改了/z的数据blog

3. B读取Zookeeper的/z的数据进程

4. 因为B链接的Zookeeper的服务器有可能尚未获得A写入数据的更新,那么B将读不到A写入的数据

 

  • 知足因果一致性的作法

1. B进程监听Zookeeper上/z的数据变化

2. A进程向Zookeeper的/z写入一个数据,成功返回前,Zookeeper须要调用注册在/z上的监听器,Leader将数据变化的通知告诉B

3. B进程的事件响应方法获得响应后,去取变化的数据,那么B必定可以获得变化的值

4. 这里的因果一致性提如今Leader和B之间的因果一致性,也就是是Leader通知了数据有变化

 

第二种事件监听机制也是对Zookeeper进行正确编程应该使用的方法,因此,Zookeeper应该是知足因果一致性的

 

 

读你所写(写后读)一致性

严格来讲,Zookeeper不知足读你所写一致性。由于在一个进程中,以下的操做序列是Zookeeper不能保证的, 会话创建->写数据->会话关闭->会话创建->读数据,最后的读数据不必定读到以前写的数据。

 

MongoDB是否知足读你所写一致性?MongoDB是知足的,由于它是链接信息跟线程绑定的,意思是说,读写线程跟MongoDB的链接信息是绑定的,读写线程获取链接优先链接到以前链接到的服务器。

 

会话一致性

在一个会话过程当中,Zookeeper知足读你所写一致性。由于Zookeeper不一样于MongoDB或者其它分布式系统,是读写数据结束当即释放链接。而Zookeeper是长链接的(用于监听Zookeeper的事件)。

Zookeeper提供了会话的自动重连机制,当客户端链接的Zookeeper服务器出现故障而不可达时,客户端会自动尝试重连到另一台机器,客户端选择的那台服务器的数据状态不比以前链接的那台机器旧,所以会话重连也会保证会话一致性。

 

 

单调读一致性

严格来讲,Zookeeper不知足单调读一致性。由于在一个进程中,以下的操做序列是Zookeeper不能保证的, 会话创建->写数据->读数据->会话关闭->会话创建->读数据,最后的读数据不必定是以前写到的数据

 

单调写一致性

Zookeeper知足。只要Zookeeper写成功了一个操做,那么后面的写确定是在Zookeeper提交了前一个写以前,而不论是否在同一个会话中,由于Zookeeper的写操做是全局顺序性。

 

读后写一致性

Zookeeper知足读后写一致性。当Zookeeper读到一个数据后,那么Zookeeper在写数据时,一致性在读到的以后的值进行更新。