原子广播理论与Zookeeper的一致性

一、概述

原子广播是一种消息传递广播方式,他可以保证在这个系统中,所有的节点收到的消息顺序是一致的。

可见,这种协议需要保证【Hadzilacos and Toueg 1994, Chandra and Toueg 1996】:

  1. (VALIDITY) If a correct process TO-broadcasts a message m, then it eventually TO-delivers m.
  2. (UNIFORM AGREEMENT) If a process TO-delivers a message m, then all correct processes eventually TOdeliver m.
  3. (UNIFORM INTEGRITY) For any message m, every process TO-delivers m at most once, and only if m was  previously TO-broadcast by sender(m)
  4. (UNIFORM TOTAL ORDER) If processes p and q both TO-deliver messages m and m0, then p TO-delivers m before m0 if and only if q TO-delivers m before m0.

 

二、Zookeeper

paper地址:Zab: High-performance broadcast for primary-backup systems

 

符号定义与解释

𝚷:{p1,p2,....,pn} 所有的节点集合

𝛒:leader,𝛒(i)表示第i个leader 。

transaction:一个transaction分为两个部分,数据域v,版本域zxid,下文中用<v,z>表示transaction

zxid:包含两个部分 纪元epoch跟这个纪元下的counter

 

【消息M≺N当且仅当 epoch(M)<epoch(N)  ||  (epoch(M)=epoch(N) && counter(M)<  counter(N)) || (epoch(M)=epoch(N) && counter(M)== counter(N) && myid(M)<myid(N))

论文上没有myid(M)<myid(N),工程实践上会为每个节点分配一个myid】

 

定义: 

  1. ∀Q⊆𝑄:Q⊆𝚷
  2. ∀Q1,Q2⊆𝑄:Q1∧Q2≠∅

则𝑄称为法定投票集。

性质: 

  1. Integrity: 对于p(j),如果接收到了消息M且M.from=i,那么p(i)必然发送过M。
  2. Prefix:  如果p(j)接收到了一个消息M(i,j),对于消息N(i,j) happen before M(i,j),那么p(j)会在接收M之前接收到N  。
  3. Single iteration:对于p(i),p(j)的通信缓存,至多只有一轮算法迭代的的消息。

性质1表明,算法不能捏造报文。依赖于算法跟通信方式

性质2约束了消息不能乱序

zookeeper采用了primary-backup的主备模型

 

 

使用这个模型,zab重新定义了上述性质

total order:If some process delivers <v,z> before <v',z'>, then any process that delivers <v',z'> must also deliver  <v,z>, and deliver <v,z> before <v',z'>,

Agreement:If some process p(i) delivers <v,z> and some process p(j) delivers <v',z'>, then either p(i) delivers<v',z'> or p(j) delivers <v,z>

如果仅保证全序关系,可能存在不同的节点数完全不一致,Agreement让消息不要出现分叉

对于leader节点,定义性质如下

Local primary order:If a primary broadcasts <v,z> before it broadcasts <v',z'> then a process that delivers <v',z'> must also deliver  <v,z>   before <v',z'>

Global primary order: Let <v,z> and <v',z'> be as follows:

  • A primary ρ(i)  broadcasts <v,z>
  • A primary ρ(j), ρ(i) ≺ ρ(j), broadcasts <v',z'>

If a process p(i) ∊ Π delivers both <v,z> and <v',z'>, then p(i) must deliver <v,z> before <v',z'>

简而言之:同一个纪元的消息是有序的,不同纪元之间的消息也是有序的(先被broadcast的消息,先被投递)

假设我们 Local primary order可以实现,通过local order怎么实现global order。引入下面的定义

Primary integrity :If a primary ρ(e) broadcasts <v,z> and some process delivers <v',z'> such that <v',z'> has been broadcast by ρ(e'), e' < e, then ρ(e) must deliver <v',z'> before it broadcasts <v,z>。 这一点工程实践很容易实现(参见选主算法的phase2的最后一步)

 

 

zab算法的流程参照(论文跟具体实现有差异,但基本性质保持不变)

简要说明。第一阶段用来预选epoch,  第二阶段建立预选leader,第三阶段建立leader,开始广播消息。

  • f(p) Last new epoch proposal follower f acknowledged 
  • f(a) Last new leader proposal follower f acknowledged 
  • h(f) History of follower f
  • f(zxid) Last accepted transaction identifier in hf

预选epoch:  follower: 给假想的leader发create_epoch(f.p)消息。

                      leader:在接收到一个满足法定投票集所发来的create_epoch(e)后,给这个集合中的所有follower发送new_epoch(e')消息, e'大于他所收到的所有create_epoch中的纪元号

                      follower:一旦收到new_epoch(e'),则查看自己的f(p),如果f(p)<e',则f(p)=e'并且给出ack

                      leader:一旦收到这个法定投票集的所有的follwer的应答, leader选取一个transaction编号最大的h作为e'的初始化数据。

预选leader: leader:发送new_leader(e') 给这个法定投票集

                      follower:一旦收到new_leader(e') ,如果f(p)!=e',开启新一轮迭代 否则 设置f(a)=e'  并且accept I(e'),发送ack

                      leader:一旦收到过半数new_leader的ack,给所有的follower发送commit消息。(至此,leader已经建立,建立的本意就是可以commit消息)

                      follower:收到commit消息后,投递自己已经deliver过的信息与 I(e') 的差额。保证性质Primary integrity

消息广播:很简单,参照paper原文

 

 

三、证明部分

 

Zab satisfies broadcast integrity : If some follower delivers <v,z> then some primary ρ(e)∊ Π has broadcast <v,z>

这个性质只需要通讯信道保证即可

 

D(f):f在epoch=f.a的广播阶段投递的消息集合

 

Zab satisfies agreement: If some follower f delivers <v,z> and some follower f’ delivers <v',z'>, then f' delivers <v,z> or f delivers <v',z'>

证明:如果<v,z>=<v',z'>,显然成立

          不失一般性z≺z': 要么epoch(z)<epoch(z'), 要么epoch(z)==epoch(z')  并且counter(z)<counter(z')

          情况1:epoch(z)==epoch(z')  ,不失一般性,设<v',z'>∊D(f')  对于<v,z>     要么<v,z>∊D(f') =>得证

                                                                                                                                要么 <v',z'>∊I(f'.e)=>显然成立

          情况2:epoch(z)<epoch(z')      由于f’ delivers <v',z'>,则此时leader(e')已经产生  对于D(f)⊆I(e')=> <v,z>∊I(e') 根据算法phase2的最后一步,得证

 

Zab satisfies total order: If some follower delivers <v,z> before <v',z'>, then any process that delivers <v',z'> must also deliver <v,z> and deliver <v,z> before <v',z'>

证明: 在C(f.e) 上<v,z> ≺ <v',z'>,<v',z'>∊C(f'.e)

            情况1:f'.e <f.e  那么  C(f'.e)⊂C(f.e) =><v',z'>∊C(f.e) ,并且 C(f’.e) 上<v,z> ≺ <v',z'>

            情况2:f'.e≥f.e  那么   C(f.e)= CB(e)∪I(e),   C(f.e)⊆C(f'.e)  首先在C(f'.e)上有 <v,z> ≺ <v',z'>

                                                                                                        其次 ∆f'⊆C(f'.e) 并且 <v',z'>∊∆f' 

 

至此我们证明了Zookeeper算法的agreement与integrity部分

四、总结

zab算法所需要的基础设施:

  • 可靠的信道 tcp 
  • 可靠的本地存储系统  磁盘   
  • 选主算法事实上依赖了paxos算法的正确性

Zookeeper性能:

我们可以看到,算法的复杂部分是由数据写入带来的,数据读部分zk在本地内存保存了一个一致性tree。读性能>写性能,因此zk使用与读多写少的场景。论文中给定的比例大约是3:1

 

 

 

                                   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值