Zookeeper之Zab协议介绍(三)

来源:互联网 发布:中国当前网络消费现状 编辑:程序博客网 时间:2024/06/05 02:29

问题描述

 

ZooKeeper采用主备(primary-backup)方案来进行请求,并以主进程次序原子广播(primary order)将状态变化传播到备用进程。因此只有主进程才要广播。如果主进程崩溃,我们认为存在一个外部机制来选择新的主进程。然而,要保证任何时候只存在最多一个主进程并只允许该主进程进行广播是非常重要的。在我们的实现中,主进程选举机制同我们用以消息广播机制是紧密耦合的。假定存在这样的机制来选择主进程并保证在任何时间只有一个主进程工作,从协议的角度来看这已经足够了。随时间流逝,我们会有一组无限的主进程序列,ρ1ρ2…ρeρe+1…,这里ρe∈П。我们说主进程ρe先于主进程ρe’,如果e<e’。主进程次序队列(Precedence of primaries)是指按时间变化顺序的所有主进程的序列。事实上,由于进程可能恢复,所以有可能存在ρe和ρe’,这里e≠e’,但是ρe和ρe’ 却是同一个进程,但是是不同的实例。

 

为了保证所有主进程广播的事务的一致性,我们需要确保主进程仅当Zab层的恢复都已完成的情况下,才会开始发送状态变化消息。为了达到这个目的,我们假定所有进程都实现了一个ready(e)的调用,用以让Zab层来通知应用(主进程和所有备份复制进程),Zab已经可以开始广播状态变化了。ready调用同时会为变量instance设值,让主进程决定它的实例值。在广播的时候,主进程用instance变量值作为事务标识号的时间部分。我们假定e的值做所有的主进程实例中是唯一的。实例的唯一性由Zab来保证。

 

把主进程将状态变化传播给备份进程,我们称做事务。一个事务<v, z>有两个部分:事务的值v以及事务的标识z(或叫做zxid)。每个事务标识z=<e, c>,即z由两部分组成,时间标识e和计数器c。我们采用epoch(z)来标识事务标识号的时间部分,counter(z)来标识事务标识号的计数器值。我们说,时间(epoch)e是先于时间e’,即e<e’。

 

对于一个给定的主进程实例ρe,epoch(z) = instance = e。对于每一个新的事务,我们会递增计数器c。我们说事务标识号z先于事务标识号z’,即要么epoch(z)< epoch(z’),或者epoch(z) == epoch(z’)但counter(z) < counter(z’)。

一旦主进程有一个事务要广播,abcast(<v, z>)会被调用。进程调用abdeliver(<v, z>)来投递(或者提交)一个事务。abcast(<v,z>)不保证成功,譬如主进程崩溃或主进程有变化。因此,在主进程广播的状态变化序列中,只有状态变化的前缀才会被传输。一旦一个事务被传输,进程会将该事务放入txns集合。

原创粉丝点击