Distributed System: Zookeeper 和 PAXOS

来源:互联网 发布:快压软件官方 编辑:程序博客网 时间:2024/04/25 09:49

Zoopkeeper是由雅虎发明,google开源的分布式系统一致性解决方案。ZAB(ZooKeeper Atomic Broadcast,ZooKeeper原子消息广播协议)可算是最广泛应用的分布式一致性协议了,其是基于Paxos算法改善的分布式系统数据一致性协议。


ZAB强调的是事务严格按照客户端请求的顺序提交,而Paxos注重的是一个状态机模型,一致性协议保证所有的状态机副本以相同的顺序执行相同的指令,那么所有状态机可以保证以相同的状态变化进行转移。所以,ZAB在Paxos的基础上,增加了执行顺序与用户提交一致的要求。


对于Zookeeper需要知道的一些基础概念:


1)ZooKeeper对外展现的是一颗类似Unix文件系统的树形数据模型(形如/foo/path1),其基本元素称之为数据节点(ZNode)。Node可以分为持久节点和临时节点两种类型:持久节点是一旦创建后,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存;临时节点的生命周期和客户端会话相绑定的,一旦客户端会话失效,那么这个临时节点将会被自动移除。


但是,ZNode并不是用来存储数据的,它是用来维护Zookeeper里面的数据的时间戳的。它持有一个状态数据结构(stat),此结构中包含数据更新的版本号。每当ZNode中的数据更新时,版本号都会递增。例如,当客户端获取数据时,它(客户端)也会接收到此数据对应的版本号。当此客户端下次执行更新(或删除)数据操作时,它必须向ZNode提供这些数据的版本号(是客户端当前持有的版本号)。如果此版本号与ZNode本身的版本号不一致,即其他客户端已经更新了此数据,那么此更新就会执行失败。


2)它如何利用PAXOS的思想维护一致性?


既然是从PAXOS发展而来,那么其拥有的角色就应该和PAXOS是一样的:Leader, Client, Follower. 


在集群一开始时,要选举Leader并不同proposal ID. 接着:


从Client的角度上,Client可以向集群的任何一台机器发送请求,如果该请求会引发状态机的改变(非只读请求),就会被转发到Leader节点;而任何节点都可以直接处理Client的只读类请求,这样一定程度上保证了系统的高可用性,而Client如果想要保证只读请求事务得到的副本是最新的,可以向其直接连接的服务器发送sync请求。


当其中一个follower给leader发送更改请求之后,根据ZAB规定,集群中只有唯一的Leader,负责处理所有客户端的变更事务请求,通过广播的形式将事务传输到其他Fellower节点上形成副本,每当Fellower接收到事务后首先将其以事务日志的形式固化保存到本地,并向Leader返回Ack确认信息;当Leader一旦收到超过半数的Fellower节点的Ack反馈后,Leader就会再次向所有的Fellower节点发送Commit消息进行事务提交。这种主备的工作形式和2PC十分相像,但是两者还是有着本质的差异。最重要的差异在于它不需要等所有的节点都同意就可以commit改变。因为有PAXOS的状态机记录,如果暂时有节点挂掉了,然后又恢复了,可能从其他的状态机备份中获得需要跟上的状态记录。同时,也是最重要的一点,ZAB保证会按照客户端的事务请求顺序执行事务提交的,因此保证了严格的因果一致性。


对于PAXOS协议,有一个很好的比喻版本:(参考:http://chuansong.me/n/285625951945)


假设有一个社团,其中有团员、议员(决议小组成员)两个角色


团员可以向议员申请提案来修改社团制度


议员坐在一起,拿出自己收到的提案,对每个提案进行投票表决,超过半数通过即可生效


为了秩序,规定每个提案都有编号ID,按顺序自增


每个议员都有一个社团制度笔记本,上面记着所有社团制度,和最近处理的提案编号,初始为0


投票通过的规则:


新提案ID 是否大于 议员本中的ID,是 议员举手赞同


如果举手人数大于议员人数的半数,即让新提案生效


例如


刚开始,每个议员本子上的ID都为0,现在有一个议员拿出一个提案:团费降为100元,这个提案的ID自增为1


每个议员都和自己ID对比,一看 
1>0,举手赞同,同时修改自己本中的ID为1


发出提案的议员一看超过半数同意,就宣布:1号提案生效


然后所有议员都修改自己笔记本中的团费为100元


以后任何一个团员咨询任何一个议员:"团费是多少?",议员可以直接打开笔记本查看,并回答:团费为100元


可能会有极端的情况,就是多个议员一起发出了提案,就是并发的情况


例如


刚开始,每个议员本子上的编号都为0,现在有两个议员(A和B)同时发出了提案,那么根据自增规则,这两个提案的编号都为1,但只会有一个被先处理


假设A的提案在B的上面,议员们先处理A提案并通过了,这时,议员们的本子上的ID已经变为了1,接下来处理B的提案,由于它的ID是1,不大于议员本子上的ID,B提案就被拒绝了,B议员需要重新发起提案


上面就是Paxos的基本思路,对照ZooKeeper,对应关系就是:


团员 - client


议员 - server


议员的笔记本 - server中的数据


提案 - 变更数据的请求


提案编号 - zxid(ZooKeeper Transaction Id)


提案生效 - 执行变更数据的操作


ZooKeeper中还有一个leader的概念,就是把发起提案的权利收紧了,以前是每个议员都可以发起提案,现在有了leader,大家就不要七嘴八舌了,先把提案都交给leader,由leader一个个发起提案


Paxos算法就是通过投票、全局编号机制,使同一时刻只有一个写操作被批准,同时并发的写操作要去争取选票,只有获得过半数选票的写操作才会被批准,所以永远只会有一个写操作得到批准,其他的写操作竞争失败只好再发起一轮投票


因为需要过半数的赞成,所以需要至少一半的机器能工作才可以。最少3台构成一个zookeeper集群。



0 0