1.zk是分布式应用协调服务。可以做注册中心,配置中心等。 它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作 2.客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器, 这个监听器也是由所连接的zookeeper机器来处理。对于写请求,这些请求会同时发给其他zookeeper机器并且达成一致后, 请求才会返回成功。因此,随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降 3.有序性是zookeeper中非常重要的一个特性,所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为zxid 4.zk提供了文件系统和通知机制 5.zk文件系统 Zookeeper提供一个多层级的节点命名空间(节点称为znode)。与文件系统不同的是,这些节点都可以设置关联的数据, 而文件系统中只有文件节点可以存放数据而目录节点不行。Zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构, 这种特性使得Zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M. 6.四种节点 持久化节点:客户端与zookeeper断开连接后,该节点依旧存在 持久化顺序节点:客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号 临时目录节点:客户端与zookeeper断开连接后,该节点被删除 临时顺序节点:客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号 7.文件系统结构 / /NameService /Service1 /Service2 /Configuration ... 8.zk通知机制 client端会对某个znode建立一个watcher事件,当该znode发生变化时,这些client会收到zk的通知,然后client可以根据znode变化来做出业务上的改变等 9.zk可以做什么 命名服务 配置管理 注册中心 分布式锁 集群管理 10.zk命名服务 命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,即是唯一的路径, 这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。 11.zk配置管理 程序分布式的部署在不同的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时, 可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。 12.zk进行集群管理 所谓集群管理无在乎两点:是否有机器退出和加入、选举master 对于第一点,所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉, 该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道 新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了,对于第二点,我们稍微改变一下, 所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。 13.zk分布式锁 第一种锁不存在 我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点, 最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。 当存在锁时: 所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。 /locker -node1 -node2 ... 获取锁的时候在/lock节点下面创建临时有序节点 释放锁的时候删除该临时节点 客户端调用createNode方法在locker下创建临时顺序节点,然后调用getChildren(“locker”)来获取locker下面的所有子节点, 注意此时不用设置任何Watcher。 何时获取到锁? 客户端获取到所有的子节点path之后,如果发现自己创建的节点在所有创建的子节点序号最小,那么就认为该客户端获取到了锁 当自己不是最小节点时? 如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁, 此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时对其注册事件监听器 之后,让这个被关注的节点删除,则客户端的Watcher会收到相应通知,此时再次判断自己创建的节点是否是locker子节点中序号最小的, 如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听 BaseDistributedLock 14.使用zk做数据同步 Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。数据复制的好处: 1、容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作; 2、提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力; 3、提高性能:让客户端本地访问就近的节点,提高用户访问速度。 对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降 15.zk工作原理 Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。 Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后, Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。 状态同步保证了leader和Server具有相同的系统状态。 16.zk如何保证事务的顺序一致性 采用递增的事务id 所有的proposal(提议)都在被提出的时候加上了zxid,利用db的两阶段提交 + 大多数成功 17.zk 下server的状态 looking 不知道leader是谁 LEADING 当前server是leader FOLLOWING leader已经选举出来,当前Server与之同步 18.zk选主过程 当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会记录事务日志并定期进行快照,方便在恢复时进行状态恢复 19.zk同步流程 选完Leader以后,zk就进入状态同步过程。 1、Leader等待server连接; 2、Follower连接leader,将最大的zxid发送给leader; 3、Leader根据follower的zxid确定同步点; 4、完成同步后通知follower 已经成为uptodate状态; 5、Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。