zookeeper 笔记 (三)

一.    Paxos算法

1. 概述

    paxos算法是一种基于消息传递的一致性算法。这个算法被认为是类似算法中最有效的。Google Chubby的作者Mike Burrows说,这个世界上只有一种一致性算法,那就是Paxos,其它的算法都是残次品。

    Paxos是多数派决议(最终解决一致性问题),作者是莱斯利·兰伯特(Leslie Lamport),与1990年提出


2. 角色设定

Proposer:提交者(议案提交者)

          提交议案(判断是否过半),提交批准议案(判断是否过半)

Acceptor:接收者(议案接收者)

          接受议案或者驳回议案,给proposer回应(promise)

Learner:学习者(打酱油的)

         如果议案产生,学习议案。


3. 条件设定

设定1:如果Acceptor没有接受议案,那么他必须接受第一个议案
设定2:每个议案比必须有一个编号,并且编号只能增长,不能重复。越往后越大。
设定3:接受编号大的议案,如果小于之前接受议案编号,那么不接受
设定4:议案有2种(提交的议案,批准的议案)

4. 算法过程

zookeeper 笔记 (三)_第1张图片

a. 第一阶段:预提案

a)Proposer希望议案V。首先发出Prepare请求至大多数Acceptor。Prepare请求内容为序列号K
b)Acceptor收到Prepare请求为编号K后,检查自己手里是否有处理过Prepare请求。
c)如果Acceptor没有接受过任何Prepare请求,那么用OK来回复Proposer,代表Acceptor必须接受收到的第一个议案(设定1)
d)否则,如果Acceptor之前接受过任何Prepare请求(如:MaxN),那么比较议案编号,如果Ke)如果K>=MaxN,那么检查之前是否有批准的议案,如果没有则用OK来回复Proposer,并记录K
f)如果K>=MaxN,那么检查之前是否有批准的议案,如果有则回复批准的议案编号和议案内容(如:, AcceptN为批准的议案编号,AcceptV为批准的议案内容)

b. 第二阶段:正式提案

a)Proposer收到过半Acceptor发来的回复,回复都是OK,且没有附带任何批准过的议案编号和议案内容。那么Proposer继续提交批准请求,不过此时会连议案编号K和议案内容V一起提交(这种数据形式)

b)Proposer收到过半Acceptor发来的回复,回复都是OK,且附带批准过的议案编号和议案内容()。那么Proposer找到所有回复中超过半数的那个(假设为)作为提交批准请求(请求为)发送给Acceptor。

c)Proposer没有收到过半Acceptor发来的回复,则修改议案编号K为Kx,并将编号重新发送给Acceptors(重复Prepare阶段的过程)

d)Acceptor收到Proposer发来的Accept请求,如果编号K

e)Acceptor收到Proposer发来的Accept请求,如果编号K>=MaxN则批准该议案,并设置手里批准的议案为,回复Proposer。

f)经过一段时间Proposer对比手里收到的Accept回复,如果超过半数,则结束流程(代表议案被批准),同时通知Leaner可以学习议案。

经过一段时间Proposer对比手里收到的Accept回复,如果未超过半数,则修改议案编号重新进入Prepare阶段。


------>>>知乎大神对paxos的描述<<<------

二.    ZAB协议

1. 概述

    Zookeeper Automic Broadcast(ZAB),是paxos经典实现。ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协议作为其数据一致性的核心算法。

2. 角色设定

a. ZAB中节点的状态

looking:选举Leader的状态(崩溃恢复下)

following:跟随者(follower)的状态,服从Leader命令

leading:当前节点是Leader,负责协调工作。

observing:observer(观察者),不参与选举,只读节点。

b. 术语

quorum:集群过半数的集合

epoch周期值

acceptedEpoch:follower已经接受leader更改周期值的(newepoch)提议。

currentEpoch:当前的周期值

lastZxid:history中最近接收到的提议zxid(最大的值)

history:当前节点接受到事务提议的log

zxid:zookeeper的事务ID,64位的数据结构

    高32位:Leader 周期编号 myid

    低32位:事务的自增序列(单调递增的序列)只要客户端有请求,就+1


3. 算法过程

zookeeper 笔记 (三)_第2张图片

a. 崩溃恢复

zookeeper 笔记 (三)_第3张图片

1> 每个Server会发出一个投票,第一次都是投自己。投票信息:(myid,ZXID)

2> 收集来自各个服务器的投票

3> 处理投票并重新投票,处理逻辑:优先比较ZXID,然后比较myid

4> 统计投票,只要超过半数的机器接收到同样的投票信息,就可以确定leader

5> 改变服务器状态(崩溃恢复 ---> 数据同步,或者崩溃恢复 ---> 消息广播)



b. 消息广播

zookeeper 笔记 (三)_第4张图片

1> Leader接受请求后,讲这个请求赋予全局的唯一64位自增Id(zxid)。

2> 将zxid作为议案发给所有follower。

3> 所有的follower接受到议案后,想将议案写入硬盘后,马上回复Leader一个ACK(OK)。

4> 当Leader接受到合法数量Acks,Leader给所有follower发送commit命令。

5> follower执行commit命令。

ps: 到了这个阶段,ZK集群才正式对外提供服务,并且Leader可以进行消息广播,如果有新节点加入,还需要进行数据同步。


c. 数据同步

1> 取出Leader最大lastZxid(从本地log日志来)

2> 找到对应zxid的数据,进行同步(数据同步过程保证所有follower一致)。

3.  只有满足quorum同步完成,准Leader才能成为真正的Leader。



你可能感兴趣的:(note)