数据一致性实现技术

来源:互联网 发布:pc破解wifi密码软件 编辑:程序博客网 时间:2024/05/05 18:21

2.4.1 Quorum系统NRM策略

Quorum协议有三个关键值N、R和W。

N表示数据所具有的的副本数。

R表示完成读操作所需要读取的最小副本数,即一次读操作所需参与的最小节点数目。

W表示完成写操作所需要写入的最小副本数,即一次写操作所需参与的最小节点数目。


该策略中,只需保证R+W>N,就可保证强一致性。

如果R+W>N,那么分布式系统就会提供强一致性保证,因为读取数据的节点和被同步写入的节点是有重叠的。

如果R+W<=N,系统只能保证最终一致性,而副本达到一致的时间则依赖于系统异步更新的实现方式。


R和W的设置直接影响系统的性能、扩展性与一致性,下面为不同设置的几种特殊情况。

当W=1,R=N时,系统对写操作有较高的要求,但读操作会比较慢,若N个节点中有节点发生故障,那么读操作将不能完成。

当R=1,W=N时,系统要求读操作高性能、高可用,但写操作性能较低,用于需要大量读操作的系统,若N个节点有节点发生故障,那么写操作将无法完成。

当R=Q,R=Q(Q=N/2+1)时,系统在读写性能之间取得了平衡,兼顾了性能和可用性,Dynamo系统的默认设置就是这种,即N=3,W=2,R=2。


2.4.2 两阶段提交协议


两阶段提交协议(Two Phase Commit Protocol,2PC协议)可以保证数据的强一致性,是协调所有分布式原子事务参与者,并决定提交或取消(回滚)的分布式算法,同时也是解决一致性问题的一致性算法。但是,它并不能通过配置来解决所有的故障,为了能够从故障中恢复,两阶段提交协议使用日志来记录参与者(节点)的状态,虽然使用日志降低了性能,但是参与者(节点)能够从故障中恢复。


在两阶段提交协议中,系统一般包含两类机器(或节点):一类为协调者(Coordinator),通常一个系统中只有一个;另一类为事务参与者(Participants),一般包含多个。协议中假设每个节点都会记录写前日志(Write-ahead Log)并持久性存储,即使节点发生故障日志也不会丢失。协议中还假设节点不会发生永久性故障,而且任意两个节点都可以互相通信。


两阶段提交协议的执行过程如下所述:


阶段1:请求阶段(commit-request phase 或称表决阶段,voting phase)

在请求阶段,协调者通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行发生故障)。


阶段2:提交阶段(commit phase)

在该阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消。当且仅当所有的参与者同意提交,事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务。参与者在接收到协调者发来的消息后将执行相应的操作。


两阶段提交协议最大的缺点在于它是通过阻塞完成的协议,节点在等待消息的时候处于阻塞状态,节点中其他进程则需要等待阻塞进程释放资源。同时两阶段提交协议没有容错机制,一个节点发生故障整个事务都要回滚,代价比较大。基于此,后来有人提出了三阶段提交协议,引入了超时机制;为了能够更好的解决实际的问题,两阶段提交协议存在很多的变种,例如:树形两阶段提交协议、动态两阶段提交协议等。


2.4.3 时间戳策略


时间戳策略在关系数据库中有广泛的应用,该策略主要用于关系数据库日志系统中记录事务操作,以及数据恢复时的Undo/Redo等操作。在并行系统中,时间戳策略有更加广泛的应用。


在并行数据存储系统或并行数据库中,数据间的同步问题可由时间戳策略很好的缓解,但是不同节点间物理时钟的偏差会导致较早更新的数据其时间戳却比较晚,虽然全局时钟可以解决上述问题,但也会导致开销太大,系统效率过低,全局时钟宕机,系统将无法工作等新的问题。因此,该系统时钟将成为系统效率和可用性的瓶颈。


对时间戳策略进行改进,使其不依赖于任何单个的节点,也不依赖于物理时钟的同步。该时间戳为逻辑上的时钟,并且通过时间戳版本的更新可以在系统中生成一个全局有序的逻辑关系。


下面我们将简单介绍该策略的核心思想。


2.4.3.1 时间戳


时间戳最早用于分布式系统中进程之间的控制,用来确定分布式系统中事件的先后关系,可协调分布式系统中的资源控制。


假设发送或接受消息是进程的一个事件,下面我们来定义分布式系统事件集中的先后关系,用“->”符号来表示,利用时间a发生在时间b之前,那么a->b。

该关系需要满足下列三个条件:

如果事件a和事件b是同一进程中的事件,并且a在b之前发生,那么a->b。

如果事件a是某消息发送方进程中的事件,事件b是该消息接收方进程中接收该消息的事件,那么a->b。

对于事件a、事件b和事件c,如果有a->b和b->c,那么a->c。


2.4.3.2 逻辑时钟


这里为每一个进程Pi定义一个时钟Ci,该时钟能够为任意一个事件a分配一个时钟值:Ci(a)。在全局上,同样存在一个时钟C,对于事件b,该时钟能够分配一个时钟值C(b),并且如果事件b发生在Pi上,那么C(b)=Ci(b)。


时钟条件:如果对于事件a和事件b,a->b,那么C(a)<C(b)。

C1:如果事件a和事件b是同一个进程Pi中的事件,并且a在b之前发生,那么:Ci(a)<Ci(b)

C2:如果a为进程Pi上某消息发送事件,b为进程Pj上该消息接收事件,那么:Ci(a)<Cj(b)

IR1:对于同一节点上任意的连续事件来说,该节点上的时钟只需要保证较晚发生事件的时钟值大于较早发生事件的时钟值即可。

IR2:(a)如果事件a代表节点Ni发送消息m,那么消息m将携带事件戳Tm,且Tm=Ci(a);(b)当节点Nj接收到消息m后,节点将设置该事件的时钟Cj大于或等于该节点上一事件的时钟并且大于或等于Tm。


该理论为时间戳的基本理论,具体的系统和实现要根据当前环境来决定。其中向量时钟技术为时间戳策略的演变,能够更好的解决实际中的问题,详见2.4.5节。


2.4.4 Paxos


Paxos算法常用于具有较高容错性的分布式系统中,其核心就是一致性算法,该算法解决的问题就是一个分布式系统如何就某个值(决议)达成一致。目前,开源分布式系统Hadoop中的Zookeeper为Paxos算法的开源实现。


一致性保证需要满足以下条件:

  • 提议只能被提出后才能被选择。
  • 算法的一次执行实例中只能选择一个提议。
  • 提议只有被选中后才能让其他节点(learner)所知道。

该算法的目的是保证某个提出的提议最终能够被选择,而且一旦被选中后,其他节点最终能够知道这个值。


在一致性算法中有三种角色:提议者(proposer)、批准者(acceptor)、学习者(learner)。在具体实现中,一个节点可以担当多个角色。

假设节点之间通过发送消息进行通信,这里使用常用的异步、非拜占庭模型。在该模型中:

节点以任意速度进行操作,可能因为故障而停止,也可以重新启动。并且节点所选择的提议不会因为重启等其他故障而消失。

消息可以延迟发送、多次发送或丢失,但不会被篡改。


选择提议算法过程如下:

阶段1:准备阶段

(1)提议者选择一个恰当的版本号n,并发送一个版本号为n的“准备请求”到一个批准者的大多数集。

(2)如果某个批准者接收到该“准备请求”,并且该请求的版本号n大于该批准者之前所响应过的任意“准备请求”的版本号,那么此批准者将向该提议者承诺不会再响应任何版本号低于n的提议,并告知提议者它曾经批准过的提议的最高版本号。

阶段2:批准阶段

(1)如果提议者接收到来自大多数集的对于其关于版本号为n的“准备请求”的响应信息,那么它向该(或其他)大多数集发送关于“版本号为n、值为v的提议”的“批准请求”,如果该响应信息不为空,其中v的值为该响应信息中最高版本号提议的值;如果该响应信息为空,那么提议者可以自主指定新的提议的值。

(2)如果某批准者接收到了关于版本号为n的提议的“批准请求”,那么除非它曾响应过版本号大于n的提议的“准备请求”,否则它将批准该提议。


学习选择的提议:为了能够学习已被批准的提议,学习者需要找到被大多数集所批准的提议。


其他问题:有可能有两个不同的提议者不断尝试提出更高版本的提议,并且任何一个都不会被选择为提议。为了保证系统的正常运行,需要选出某个提议者作为唯一的提议者来发出提议。Zookeeper中使用的正是这种策略,被称为“领导选取”。


2.4.5 向量时钟


向量时钟(Vector Clock)是一种在分布式环境中为各种操作或事件产生偏序值的技术,它可以检测操作或事件的并行冲突,用来保持事件的一致性。向量时钟方法在分布式系统中用于保证操作的有序性和数据的一致性。向量时钟通常可以被认为是一组来自不同节点的时钟值Vi[1]、Vi[2]、…Vi[n]。Vi[n]是第i个节点所了解的第n个节点上的时钟值。


下面具体描述向量时钟在分布式系统中的运维规则。

规则1:初始时,我们将每个节点的值设置为0,。每当有数据更新发生,该节点所维护的时钟值将增长一定的步数d,d的值通常由系统提前设置好。

规则2:在节点i的数据更新之前,我们对节点i所维护的向量Vi进行更新:Vi[i]=Vi[i]+d (d>0)。

规则3:当节点i向节点j发送更新消息时,将携带自身所了解的其他节点的向量时钟信息。节点将根据接收到的向量与自身所了解的向量时钟信息进行比对,然后进行更新:Vj[k]=max{ Vi[k],Vj[k] }。 在合并时,节点j的向量时钟每一维的值取节点i与节点j向量时钟该维度值的较大者。


两个向量时钟是否存在偏序关系,通过以下规则进行比较:

对于n维向量来说,Vi>Vj,如果任意k(0<=k<=n-1)均有Vi[k] > Vj[k]。

如果Vi既不大于Vj且Vj也不大于Vi,这说明在并行操作中发生了冲突,这时需要采用冲突解决方法进行处理,比如合并。


相对于其他方法,向量时钟的主要优势在于:

  • 节点之间不需要同步时钟,即不需要全局时钟。
  • 不需要在所有节点上存储、维护一段数据的版本数。

该方法的主要缺点是向量时钟值的大小与参与的用户有关,在分布式系统中参与的用户很多,随着时间的推移,向量时钟值会增长到很大。

向量时钟在实现中有两个主要问题:如何确定持有向量时钟值的用户,如何防止向量时钟值随着时间不断增长。





0 0
原创粉丝点击