**# 1.zookeeper** 它是一个分布式开源的应用程序协调服务,它是集群的管理者,监视着集群中各个节点的状态,根据节点提交的反馈进行下一步合理操作,最终将简单易用的接口和性能高效,功能稳定的系统提供给用户 它提供了文件系统,通知机制 **# 2.文件系统(znode)** 每个子目录项如 NameService 都被称作为znode,和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。 有四种类型的znode: <1>、PERSISTENT-持久化目录节点 客户端与zookeeper断开连接后,该节点依旧存在 <2>、PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点 客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 <3>、EPHEMERAL-临时目录节点 客户端与zookeeper断开连接后,该节点被删除 <4>、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点 客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 **# 3.Zookeeper通知机制** 客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。 **# 4.Zookeeper做了什么?** 1.命名服务 2.配置管理 3.集群管理 4.分布式锁 5.队列管理 **# 5.分布式与数据复制 ** Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。数据复制的好处: <1>、容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作; <2>、提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力; <3>、提高性能:让客户端本地访问就近的节点,提高用户访问速度。 **# 6.从客户端读写访问的透明度来看,数据复制集群系统分下面两种:** <1>、写主(WriteMaster) :对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离; <2>、写任意(Write Any):对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。 对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。 **# 7.角色和描述** 角色:领导者(Leader) 描述:领导者负责进行投票的发起和决议,更新系统状态 角色:学习者(Learner) ---又分为 跟随者:(Follower) 和 观察者: (obServer) ---跟随者:用于接收客户请求并向客户端返回结果,在选主过程中参与投票。 ---观察者:可以接收客户端连接,将请求转发给领导者节点,但是它不参加投票的过程,只是同步领导者的状态,它的目的是为了扩展系统,提高读取速度。 角色:客户端 (Client) 描述:请求发起方 **# 8.zookeeper工作原理** Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。 为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。 **# 9.zookeeper下Server工作状态** 每个Server在工作过程中有三种状态: LOOKING:当前Server不知道leader是谁,正在搜寻 LEADING:当前Server即为选举出来的leader FOLLOWING:leader已经选举出来,当前Server与之同步 **# 10.Zookeeper选主流程(basic paxos)** 当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。 <1>. 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server; <2>. 选举线程首先向所有Server发起一次询问(包括自己); <3>. 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中; <4>. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server; <5>. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。 通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1. 每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。 **# 11.Zookeeper同步流程** 选完Leader以后,zk就进入状态同步过程。 <1>. Leader等待server连接; <2>. Follower连接leader,将最大的zxid发送给leader; <3>. Leader根据follower的zxid确定同步点; <4>. 完成同步后通知follower 已经成为uptodate状态; <5>. Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。 **# 12.Zookeeper工作流程-Leader** <1> .恢复数据; <2> .维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型; <3> .Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。 PING 消息是指Learner的心跳信息; REQUEST消息是Follower发送的提议信息,包括写请求及同步请求; ACK消息是 Follower的对提议的回复,超过半数的Follower通过,则commit该提议; REVALIDATE消息是用来延长SESSION有效时间。 **# 13.Zookeeper工作流程-Follower** Follower主要有四个功能: <1>. 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息); <2>. 接收Leader消息并进行处理; <3>. 接收Client的请求,如果为写请求,发送给Leader进行投票; <4>. 返回Client结果。 **# 14.返回Client结果。** Follower的消息循环处理如下几种来自Leader的消息: <1> .PING消息: 心跳消息; <2> .PROPOSAL消息:Leader发起的提案,要求Follower投票; <3> .COMMIT消息:服务器端最新一次提案的信息; <4> .UPTODATE消息:表明同步完成; <5> .REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息; <6> .SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。