概要
ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
本文仅阐述ZooKeeper工作原理,对于如何使用ZooKeeper本文不做讨论。
ZooKeeper的特性
原子性:一个update操作不是成功就是失败,不会有第三种状态出现。
顺序性:在一个ZooKeeper集群中,其中一台ZooKeeper服务器上的消息a在消息b之前发布,那么在所有的ZooKeeper服务器上的消息a都会在消息b之前被发布,ZooKeeper会保持一致顺序。
实时性:对于每个client,ZooKeeper集群中的所有服务器都会保持实时更新制度,使得所有的服务视图都会是最新的。
统一镜像:client无论连接到集群中的哪一个ZooKeeper服务,都是得到同样的镜像视图。
可靠性:如果一个update请求被集群中其中某一台ZooKeeper服务接受了,那么就等于被所有ZooKeeper服务接受了;只有下次的update请求进来才会发生改变。
ZooKeeper 集群中存在的各种角色
角色名称 | 职责 |
领导者(Leader) | 就是ZooKeeper集群的老大,它不接受client的请求,是管理其他ZooKeeper服务的,只负责进行投票的发起和决议,最终更新状态 |
追随者(Follower) | 追随者(Follower)的上司是领导者(Leader),参与领导者(Leader)发起的投票,向下是面向客户端的交互,用于接收客户端的请求和反馈客户端的结果。参与领导者(Leader)发起的投票。 |
观察者(Observer) | 观察者可以接收客户端连接,将写请求转发给领导者(Leader)节点。但是Observer不参加投票过程,只是同步领导者(Leader)的状态。Observer为系统扩展提供了一种方法。 |
ZooKeeper集群在没有(观察者角色)的情况下的运作
通常ZooKeeper由2n+1台servers组成集群服务,每个server都知道彼此的存在。每个server都维护有内存状态镜像以及持久化存储的事务日志和快照。对于2n+1台server,只要有n+1台(大多数)server可用,整个系统保持可用。
系统启动时,集群中的server会选举出一台server为领导者(Leader),其它的就作为追随者(Follower),接着由追随者(Follower)来服务client的请求,对于不改变系统一致性状态的读操作,由追随者(Follower)的本地内存数据库直接给client返回结果;对于会改变系统状态的更新操作,则交由领导者(Leader)进行提议投票,超过半数通过后返回结果给client。
ZooKeeper工作原理
ZooKeeper的核心是原子广播,这个机制保证了各个server之间的同步。实现这个机制的协议叫做Zab协议。
Zab协议有两种模式,它们分别是恢复模式和广播模式。
恢复模式:一般是在服务刚启动或者在领导者(Leader)崩溃后,开始进入恢复模式,此时先就会开始选举领导者(Leader),当领导者(Leader)被选举出来,并且追随者(Follower)完成了和当前领导者(Leader)的状态及数据同步以后,恢复模式就结束了。
广播模式:恢复模式结束后,即领导者(Leader)已经和追随者(Follower)进行了状态同步以后,他就可以开始广播消息了,即进入广播状态(开始当国王来管束子民)。
在集群中动态新增一个新的ZooKeeper实例节点
这时候当一个新的ZooKeeper实例加入到当前的集群中时,它会在恢复模式下启动,然后去寻找当前集群的领导者(Leader),并与领导者(Leader)进行状态数据同步。直到同步结束,它也参与消息广播,此时他也成为了一名追随者(Follower)。
总之,ZooKeeper服务一直维持在广播模式状态,直到领导者(Leader)崩溃了或者领导者(Leader)失去了大部分的追随者(Follower)的支持。
广播模式(ZooKeeper集群处理事务的逻辑规则)
广播模式模式极其类似于分布式事务中的2pc(two-phrase commit 两阶段提交):即领导者(Leader)提起一个决议,由追随者(Follower)s进行投票,领导者(Leader)对投票结果进行计算决定是否通过该决议,如果通过执行该决议(事务),否则什么也不做。
广播模式需要保证提议(proposal)被按顺序处理,因此ZooKeeper采用了递增的事务id号(zxid)来保证。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64为的数字,它高32位是epoch用来标识领导者(Leader)关系是否改变,每次一个领导者(Leader)被选出来,它都会有一个新的epoch。低32位是个递增计数。
当领导者(Leader)崩溃或者领导者(Leader)失去大多数的追随者(Follower),这时候ZooKeeper进入恢复模式,恢复模式需要重新选举出一个新的领导者(Leader),让所有的server都恢复到一个正确的状态。
恢复模式中 选举领导者(Leader)的规则
首先看一下选举的过程,ZooKeeper的实现中用了基于paxos算法(主要是fastpaxos)的实现。具体如下:
1.每个Server启动以后都询问其它的Server它要投票给谁。
2.对于其他server的询问,server每次根据自己的状态都回复自己推荐的领导者(Leader)的id和上一次处理事务的zxid(系统启动时每个server都会推荐自己)
3.收到所有Server回复以后,就计算出zxid最大的哪个Server,并将这个Server相关信息设置成下一次要投票的Server。
4.计算这过程中获得票数最多的的sever为获胜者,如果获胜者的票数超过半数,则改server被选为领导者(Leader)。否则,继续这个过程,直到领导者(Leader)被选举出来。
此外恢复模式下,如果是重新刚从崩溃状态恢复的或者刚启动的的server还会从磁盘快照中恢复数据和会话信息。(ZooKeeper会记录事务日志并定期进行快照,方便在恢复时进行状态恢复)
选完领导者(Leader)以后,ZooKeeper就进入状态同步过程。
1.领导者(Leader)就会开始等待server连接
2.追随者 (Follower) 连接 领导者(Leader),将最大的zxid发送给领导者(Leader)
3.领导者(Leader)根据追随者(Follower)的zxid确定同步点
4.完成同步后通知追随者(Follower) 已经成为uptodate状态
5.追随者 (Follower) 收到uptodate消息后,又可以重新接受client的请求进行服务了。