1.zookeeper是什么?
zookeeper是一个开源的分布式数据一致性的解决方案,分布式应用程序可以基于zookeeper实现数据发布订阅,负载均衡,命名服务,分布式协调,集群管理,分布式锁和分布式队列等一系列功能,可以保证如下分布式一致性特性:
1)顺序一致性:从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到zookeeper中去;
2)原子性:要么整个集群所有机器都成功应用了某一个事务,要么都没有应用,一定不会出现集群中部分机器应用了该事务,而另外一部分没有应用的情况;
3)单一视图:无论客户端连接的是哪个zookeeper服务器,其看到的服务器算数据模型都是一致的;
4)可靠性:一旦服务端成功得应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更会一致被保留下来,除非有另外一个事务又对其进行了变更;
5)实时性:zookeeper仅仅保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态。
2.ZAB协议是什么?
ZAB协议是一种专门为zookeeper设计的一种支持崩溃回复的原子广播协议,是一种通用的分布式一致性算法,基于该协议,zookeeper实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。具体来说,zookeeper使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更为以事务的形式广播到所有的副本进程上去,该协议的这个主备模式架构保证了同一时刻集群中只能够有一个主进程来广播服务器的状态变更。
简言之,该协议核心就是定义了对于那些会改变zookeeper服务器数据状态的事务请求的处理方式,所有事务请求都必须由一个全局唯一的服务器来协调处理,即leader服务器。
3.zookeeper为什么能保证全局数据一致性?
(1)首先,zookeeper集群每个节点都可以接收到客户端请求;
(2)其次,客户端请求分为两种请求,一种请求是事务性请求,另一种是非事务性请求,下边就这两种请求展开论述:
1)事务性请求:
当事务性请求是从节点接收到的,就会将请求转发给主节点,然后让主节点按照时间顺序来指定各个节点完 成请求;当事务性请求是主节点接收到的,主节点将会直接自己按照客户端请求顺序来处理请求;
2)非事务性请求:任何节点收到了都可以自行处理;
4.主从集群和主备集群的区别?
1)主从集群:一主多从,主从各司其职,主节点负责资源分配和任务调度,从节点负责具体的执行;
2)主备集群:一主一备,主要是为了解决单点故障问题,便于备份恢复
5.zookeeper的功能?
1)小文件系统;
2)watcher监控机制;
3)选举制度
6.zookeeper都做了什么?
1)命名服务:注册中心,被用作提供服务地址,例如dubbo中zk就是被用作注册中心的,专门记录一些全局路径,需要先在zk中注册地址,然后当有请求需要访问某个地址的时候,可以直接在zk中找到对应的地址去请求相应服务,就类似于一个总目录一样;
2)配置信息(watcher监控机制):程序分布式的部署在不同的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。
3)集群管理:无非就是是否有新的机器加入或者机器被删除,以及选举主节点
4)分布式锁:(监控机制,这块理解的还不是很透彻)
有了zookeeper的全局一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
对于独占锁,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建的distribute_lock 节点就释放出锁。
对于控制时序锁, distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次执行。
7.zookeeper是怎么选举出来leader的?或者说选举机制是怎样的?
当leader崩溃或者leader失去大多数的follower时,zk就进入恢复模式,恢复模式即需要重新选举出一个新的leader,让所有的节点都恢复到一个正确的状态。
Zk的选举算法有两种:一种是基于BasicLeaderElection实现的,另外一种是基于FastLeaderElection算法实现的。系统默认的选举算法为FastLeaderElection
基于BasicLeaderElection算法的选举机制:
(1)选举线程是一个独立的线程,其主要功能是对投票结果进行统计,并选出推荐的Server;
(2)选举线程首先向所有节点发起一次询问(包括自己);在收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
(3)收到所有节点回复以后,就计算出zxid最大的那个节点,并将这个节点相关信息设置成下一次要投票的节点;
(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会记录事务日志并定期进行快照,方便在恢复时进行状态恢复
基于FastLeaderElection算法的选举机制:
FastLeaderElection算法选举流程是在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
基于FastLeaderElection算法的选举机制的两种情况下选举:
第一种:全新选举
假设目前有 5 台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,
它们的选择举过程如下:
l 服务器 1 启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器 1 的状态一直属于 Looking。
l 服务器 2 启动,给自己投票,同时与之前启动的服务器 1 交换结果,由于服务器 2 的编号大所以服务器 2 胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是 LOOKING。
l 服务器 3 启动,给自己投票,同时与之前启动的服务器 1,2 交换信息,由于服务器 3 的编号最大所以服务器 3 胜出,此时投票数正好大于半数,所以服务器 3 成为领导者,服务器 1,2 成为小弟。
l 服务器 4 启动,给自己投票,同时与之前启动的服务器 1,2,3 交换信息,尽管服务器 4 的编号大,但之前服务器 3 已经胜出,所以服务器 4 只能成为小弟。
l 服务器 5 启动,后面的逻辑同服务器 4 成为小弟
第二种:非全新选举
对于运行正常的 zookeeper 集群,中途有机器 down 掉,需要重新选举时,选举过程就需要加入数据 ID、服务器 ID 和逻辑时钟。
这样选举的标准就变成:
1、逻辑时钟小的选举结果被忽略,重新投票;
2、统一逻辑时钟后,数据 id 大的胜出;
3、数据 id 相同的情况下,服务器 id 大的胜出;
根据这个规则选出 leader。