zookeeper学习笔记(转载)


一个分布式的,开放源码的分布式协调服务,是Hadoop和Hbase的重要组件;它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

特点:

  1. ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
  2. ZooKeeper包含一个简单的原语集,提供Java和C的接口。
  3. ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。

Paxos算法

拜占庭将军问题
	拜占庭帝国就是5~15世纪的东罗马帝国,拜占庭即现在土耳其的伊斯坦布尔。我们可以想象,拜占庭军队有许多分支,驻扎在敌人城外,每一分支由各自的将军指挥。将军们只能靠通讯员进行通讯。在观察敌人以后,忠诚的将军们必须制订一个统一的行动计划——进攻或者撤退。然而,这些将军中有叛徒,他们不希望忠诚的将军们能达成一致,因而影响统一行动计划的制订与传播。
	问题是:将军们必须有一个协议,使所有忠诚的将军们能够达成一致,而且少数几个叛徒不能使忠诚的将军们作出错误的计划——使有些将军进攻而另一些将军撤退。
	如果这11位将军中有间谍呢? 假设有9位忠诚的将军,5位判断进攻,4位判断撤退,还有2个间谍恶意判断撤退,虽然结果是错误的撤退,但这种情况完全是允许的。因为这11位将军依然保持着状态一致性。

1.11位将军进攻城池
2.同时进攻(议案、决议)、同时撤退(议案、决议)
3.不管撤退还是进攻,必须半数的将军统一意见才可以执行
4.将军里面有叛徒,会干扰决议生成

在Paxos算法面前,其他(包括2P、3P)都是残次品。Google Chubby的作者Mike Burrows说过这个世界上只有一种一致性算法,那就是Paxos,其它的算法都是残次品。
Paxos算法思想

多数派决议(最终解决一致性问题)
有些类似于法案颁发的“民主”决策:

  1. 提案者先分发草案给各议员采集意见,议员用自己的接收准则进行回复(未接收过则接收并回复OK;否则比较与之前接收过的编号大小,大於则替换并回复OK,不然回复ERROR);
  2. 提案者接收回复,集中判断——多数派为胜(否则从头递归),提出筛选过的准法案再次分发确认,议员接收批准方案再进行回复(类似于1的回复规则);
  3. 提案者第二接收回复,判断准法案成功与否,成功即为正式法案(否则从头递归)。

三种角色:
(1)Proposer:(议案)提交者
提交议案(判断是否过半),提交批准议案(判断是否过半)
(2)Acceptor:(议案)接收者
接受议案或者驳回议案,给proposer回应(promise)
(3)Learner: (议案)学习者(打酱油的)
如果议案产生,学习议案。

规则约定
设定1:如果Acceptor没有接受议案,那么他必须接受第一个议案
设定2:每个议案必须有一个编号,编号惟一且递增。
设定3:只接受编号大的议案,小于之前接受议案编号不接受
设定4:议案有2种(提交的议案,批准的议案)

选举过程

在这里插入图片描述
选举解说:

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

  2. Accept阶段(批准阶段)
    a)Proposer收到过半Acceptor发来的回复,回复都是OK,且没有附带任 何批准过的议案编号和议案内容。那么Proposer继续提交批准请求,不过此时会连议案编号K和议案内容V一起提交(<K, V>这种数据形式)
    b)Proposer收到过半Acceptor发来的回复,回复都是OK,且附带批准过的议案编号和议案内容(<pok,议案编号,议案内容>)。那么Proposer找到所有回复中超过半数的那个(假设为<pok,AcceptNx,AcceptVx>)作为提交批准请求(请求为<K,AcceptVx>)发送给Acceptor。
    c)Proposer没有收到过半Acceptor发来的回复,则修改议案编号K为Kx,并将编号重新发送给Acceptors(重复Prepare阶段的过程)
    d)Acceptor收到Proposer发来的Accept请求,如果编号K<MaxN则不回应或者reject。
    e)Acceptor收到Proposer发来的Accept请求,如果编号K>=MaxN则批准该议案,并设置手里批准的议案为<K,接受议案的编号,接受议案的内容>,回复Proposer。
    f)经过一段时间Proposer对比手里收到的Accept回复,如果超过半数,则结束流程(代表议案被批准),同时通知Leaner可以学习议案。
    g)经过一段时间Proposer对比手里收到的Accept回复,如果未超过半数,则修改议案编号重新进入Prepare阶段。

Paxos例子

  1. 先后提议的场景

角色:
proposer:参谋1,参谋2
acceptor:将军1,将军2,将军3(决策者)

  1. 参谋1发起提议,派通信兵带信给3个将军,内容为(编号1);

  2. 3个将军收到参谋1的提议,由于之前还没有保存任何编号,因此把(编号1)保存下来,避免遗忘;同时让通信兵带信回去,内容为(ok);

  3. 参谋1收到至少2个将军的回复,再次派通信兵带信给3个将军,内容为(编号1,进攻时间1);

  4. 3个将军收到参谋1的时间,把(编号1,进攻时间1)保存下来,避免遗忘;同时让通信兵带信回去,内容为(Accepted);

  5. 参谋1收到至少2个将军的(Accepted)内容,确认进攻时间已经被大家接收;

  6. 参谋2发起提议,派通信兵带信给3个将军,内容为(编号2);

  7. 3个将军收到参谋2的提议,由于(编号2)比(编号1)大,因此把(编号2)保存下来,避免遗忘;又由于之前已经接受参谋1的提议,因此让通信兵带信回去,内容为(编号1,进攻时间1);

  8. 参谋2收到至少2个将军的回复,由于回复中带来了已接受的参谋1的提议内容,参谋2因此不再提出新的进攻时间,接受参谋1提出的时间;

在这里插入图片描述

  1. 交叉场景
    proposer:参谋1,参谋2
    acceptor:将军1,将军2,将军3(决策者)

  2. 参谋1发起提议,派通信兵带信给3个将军,内容为(编号1);

  3. 3个将军的情况如下
    a)将军1和将军2收到参谋1的提议,将军1和将军2把(编号1)记录下来,如果有其他参谋提出更小的编号,将被拒绝;同时让通信兵带信回去,内容为(ok);
    b)负责通知将军3的通信兵被抓,因此将军3没收到参谋1的提议;

  4. 参谋2在同一时间也发起了提议,派通信兵带信给3个将军,内容为(编号2);

  5. 3个将军的情况如下
    a)将军2和将军3收到参谋2的提议,将军2和将军3把(编号2)记录下来,如果有其他参谋提出更小的编号,将被拒绝;同时让通信兵带信回去,内容为(ok);
    b)负责通知将军1的通信兵被抓,因此将军1没收到参谋2的提议;

  6. 参谋1收到至少2个将军的回复,再次派通信兵带信给有答复的2个将军,内容为(编号1,进攻时间1);

  7. 2个将军的情况如下
    a)将军1收到了(编号1,进攻时间1),和自己保存的编号相同,因此把(编号1,进攻时间1)保存下来;同时让通信兵带信回去,内容为(Accepted);
    b)将军2收到了(编号1,进攻时间1),由于(编号1)小于已经保存的(编号2),因此让通信兵带信回去,内容为(Rejected,编号2);

  8. 参谋2收到至少2个将军的回复,再次派通信兵带信给有答复的2个将军,内容为(编号2,进攻时间2);

  9. 将军2和将军3收到了(编号2,进攻时间2),和自己保存的编号相同,因此把(编号2,进攻时间2)保存下来,同时让通信兵带信回去,内容为(Accepted);

  10. 参谋2收到至少2个将军的(Accepted)内容,确认进攻时间已经被多数派接受;

  11. 参谋1只收到了1个将军的(Accepted)内容,同时收到一个(Rejected,编号2);参谋1重新发起提议,派通信兵带信给3个将军,内容为(编号3);

  12. 3个将军的情况如下
    a)将军1收到参谋1的提议,由于(编号3)大于之前保存的(编号1),因此把(编号3)保存下来;由于将军1已经接受参谋1前一次的提议,因此让通信兵带信回去,内容为(编号1,进攻时间1);
    b)将军2收到参谋1的提议,由于(编号3)大于之前保存的(编号2),因此把(编号3)保存下来;由于将军2已经接受参谋2的提议,因此让通信兵带信回去,内容为(编号2,进攻时间2);
    c)负责通知将军3的通信兵被抓,因此将军3没收到参谋1的提议;

  13. 参谋1收到了至少2个将军的回复,比较两个回复的编号大小,选择大编号对应的进攻时间作为最新的提议;参谋1再次派通信兵带信给有答复的2个将军,内容为(编号3,进攻时间2);

  14. 将军1和将军2收到了(编号3,进攻时间2),和自己保存的编号相同,因此保存(编号3,进攻时间2),同时让通信兵带信回去,内容为(Accepted);

  15. 参谋1收到了至少2个将军的(accepted)内容,确认进攻时间已经被多数派接受。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章