Zookeeper面试23连问,直击灵魂,这谁顶的住?


前言:

最近不少程序员朋友都在准备折金三银四跳槽,由于疫情也在家呆了一段时间了,在家呆着也不能忘了给本身充充电呀,为了跳槽加薪,因此我要开始刷面试题了,今天给你们分享一下zookeeper的面试题,含答案哦,文末还有福利分享。node


06310aaf-b3dd-4d7a-af60-11eeddcf3738



1.ZooKeeper是什么?

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操做。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户。nginx

客户端的读请求能够被集群中的任意一台机器处理,若是读请求在节点上注册了监听器,这个监听器也是由所链接的zookeeper机器来处理。对于写请求,这些请求会同时发给其余zookeeper机器而且达成一致后,请求才会返回成功。所以,随着zookeeper的集群机器增多,读请求的吞吐会提升可是写请求的吞吐会降低。程序员

有序性是zookeeper中很是重要的一个特性,全部的更新都是全局有序的,每一个更新都有一个惟一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid。面试

2.ZooKeeper提供了什么?

一、文件系统二、通知机制算法

3.Zookeeper文件系统

Zookeeper提供一个多层级的节点命名空间(节点称为znode)。与文件系统不一样的是,这些节点均可以设置关联的数据,而文件系统中只有文件节点能够存放数据而目录节点不行。Zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得Zookeeper不能用于存放大量的数据,每一个节点的存放数据上限为1M。数据库

4.四种类型的znode

一、PERSISTENT-持久化目录节点客户端与zookeeper断开链接后,该节点依旧存在服务器

二、PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点客户端与zookeeper断开链接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号网络

三、EPHEMERAL-临时目录节点客户端与zookeeper断开链接后,该节点被删除负载均衡

四、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点客户端与zookeeper断开链接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号异步

ecd82107cfbd4a56a183ebb44821dcfa


5.Zookeeper通知机制

client端会对某个znode创建一个watcher事件,当该znode发生变化时,这些client会收到zk的通知,而后client能够根据znode变化来作出业务上的改变等。

6.Zookeeper作了什么?

  • 命名服务

  • 配置管理

  • 集群管理

  • 分布式锁

  • 队列管理

7.zk的命名服务(文件系统)

命名服务是指经过指定的名字来获取资源或者服务的地址,利用zk建立一个全局的路径,便是惟一的路径,这个路径就能够做为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。

8.zk的配置管理(文件系统、通知机制)

程序分布式的部署在不一样的机器上,将程序的配置信息放在zk的znode下,当有配置发生改变时,也就是znode发生变化时,能够经过改变zk中某个目录节点的内容,利用watcher通知给各个客户端,从而更改配置。

9.Zookeeper集群管理(文件系统、通知机制)

所谓集群管理无在意两点:是否有机器退出和加入、选举master。

对于第一点,全部机器约定在父目录下建立临时目录节点,而后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的链接断开,其所建立的临时目录节点被删除,全部其余机器都收到通知:某个兄弟目录被删除,因而,全部人都知道:它上船了。

新机器加入也是相似,全部机器收到通知:新兄弟目录加入,highcount又有了,对于第二点,咱们稍微改变一下,全部机器建立临时顺序编号目录节点,每次选取编号最小的机器做为master就好。

10.Zookeeper分布式锁(文件系统、通知机制)

有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务能够分为两类,一个是保持独占,另外一个是控制时序。

对于第一类,咱们将zookeeper上的一个znode看做是一把锁,经过createznode的方式来实现。全部客户端都去建立 /distribute_lock 节点,最终成功建立的那个客户端也即拥有了这把锁。用完删除掉本身建立的distribute_lock 节点就释放出锁。

对于第二类, /distribute_lock 已经预先存在,全部客户端在它下面建立临时顺序编号目录节点,和选master同样,编号最小的得到锁,用完删除,依次方便。

11.获取分布式锁的流程

14e962101d394b2fb1620ca60e46ae0b



在获取分布式锁的时候在locker节点下建立临时顺序节点,释放锁的时候删除该临时节点。客户端调用createNode方法在locker下建立临时顺序节点,而后调用getChildren(“locker”)来获取locker下面的全部子节点,注意此时不用设置任何Watcher。

客户端获取到全部的子节点path以后,若是发现本身建立的节点在全部建立的子节点序号最小,那么就认为该客户端获取到了锁。若是发现本身建立的节点并不是locker全部子节点中最小的,说明本身尚未获取到锁,此时客户端须要找到比本身小的那个节点,而后对其调用exist()方法,同时对其注册事件监听器。

以后,让这个被关注的节点删除,则客户端的Watcher会收到相应通知,此时再次判断本身建立的节点是不是locker子节点中序号最小的,若是是则获取到了锁,若是不是则重复以上步骤继续获取到比本身小的一个节点并注册监听。当前这个过程当中还须要许多的逻辑判断。

af5298d7b4fe4b518ecb27be0df50a57


代码的实现主要是基于互斥锁,获取分布式锁的重点逻辑在于BaseDistributedLock,实现了基于Zookeeper实现分布式锁的细节。

12.Zookeeper队列管理(文件系统、通知机制)

两种类型的队列:

  • 同步队列,当一个队列的成员都聚齐时,这个队列才可用,不然一直等待全部成员到达。

  • 队列按照 FIFO 方式进行入队和出队操做。

第一类,在约定目录下建立临时目录节点,监听节点数目是不是咱们要求的数目。

第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。在特定的目录下建立PERSISTENT_SEQUENTIAL节点,建立成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。

此场景下Zookeeper的znode用于消息存储,znode存储的数据就是消息队列中的消息内容,SEQUENTIAL序列号就是消息的编号,按序取出便可。因为建立的节点是持久化的,因此没必要担忧队列消息的丢失问题。

13.Zookeeper数据复制

Zookeeper做为一个集群提供一致的数据服务,天然,它要在全部机器间作数据复制。数据复制的好处:

  • 容错:一个节点出错,不致于让整个系统中止工做,别的节点能够接管它的工做;

  • 提升系统的扩展能力 :把负载分布到多个节点上,或者增长节点来提升系统的负载能力;

  • 提升性能:让客户端本地访问就近的节点,提升用户访问速度。

从客户端读写访问的透明度来看,数据复制集群系统分下面两种:

  • 写主(WriteMaster) :对数据的修改提交给指定的节点。读无此限制,能够读取任何一个节点。这种状况下客户端须要对读与写进行区别,俗称读写分离;

  • 写任意(Write Any):对数据的修改可提交给任意的节点,跟读同样。这种状况下,客户端对集群节点的角色与变化透明。

对zookeeper来讲,它采用的方式是写任意。经过增长机器,它的读吞吐能力和响应能力扩展性很是好,而写,随着机器的增多吞吐能力确定降低(这也是它创建observer的缘由),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,仍是当即复制快速响应。

14.Zookeeper工做原理

Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫作Zab协议。

Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步之后,恢复模式就结束了。状态同步保证了leader和Server具备相同的系统状态。

15.zookeeper是如何保证事务的顺序一致性的?

zookeeper采用了递增的事务Id来标识,全部的proposal(提议)都在被提出的时候加上了zxid,zxid其实是一个64位的数字,高32位是epoch(时期; 纪元; 世; 新时代)用来标识leader是否发生改变,若是有新的leader产生出来,epoch会自增,低32位用来递增计数。当新产生proposal的时候,会依据数据库的两阶段过程,首先会向其余的server发出事务执行请求,若是超过半数的机器都能执行而且可以成功,那么就会开始执行。

16.Zookeeper 下 Server工做状态

每一个Server在工做过程当中有三种状态:

  • LOOKING:当前Server不知道leader是谁,正在搜寻

  • LEADING:当前Server即为选举出来的leader

  • FOLLOWING:leader已经选举出来,当前Server与之同步

17.zookeeper是如何选取主leader的?

当leader崩溃或者leader失去大多数的follower,这时zk进入恢复模式,恢复模式须要从新选举出一个新的leader,让全部的Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。

一、Zookeeper选主流程(basic 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会记录事务日志并按期进行快照,方便在恢复时进行状态恢复。

a9a6f11561f9470299962c4521a23002


二、Zookeeper选主流程(basic paxos)

fast paxos流程是在选举过程当中,某Server首先向全部Server提议本身要成为leader,当其它Server收到提议之后,解决epoch和 zxid的冲突,并接受对方的提议,而后向对方发送接受提议完成的消息,重复这个流程,最后必定能选举出Leader。

af2290b4d8a0471fbd2344fe3d664628


18.Zookeeper同步流程

选完Leader之后,zk就进入状态同步过程。

  • Leader等待server链接;

  • Follower链接leader,将最大的zxid发送给leader;

  • Leader根据follower的zxid肯定同步点;

  • 完成同步后通知follower 已经成为uptodate状态;

  • Follower收到uptodate消息后,又能够从新接受client的请求进行服务了。

c8b4553fcd9f4e3391b3cb0a2a958361


19.分布式通知和协调

对于系统调度来讲:操做人员发送通知实际是经过控制台改变某个节点的状态,而后zk将这些变化发送给注册了这个节点的watcher的全部客户端。

对于执行状况汇报:每一个工做进程都在某个目录下建立一个临时节点。并携带工做的进度数据,这样汇总的进程能够监控目录子节点的变化得到工做进度的实时的全局状况。

20.机器中为何会有leader?

在分布式环境中,有些业务逻辑只须要集群中的某一台机器进行执行,其余的机器能够共享这个结果,这样能够大大减小重复计算,提升性能,因而就须要进行leader选举。

21.zk节点宕机如何处理?

Zookeeper自己也是集群,推荐配置很多于3个服务器。Zookeeper自身也要保证当一个节点宕机时,其余节点会继续提供服务。

若是是一个Follower宕机,还有2台服务器提供访问,由于Zookeeper上的数据是有多个副本的,数据并不会丢失;

若是是一个Leader宕机,Zookeeper会选举出新的Leader。

ZK集群的机制是只要超过半数的节点正常,集群就能正常提供服务。只有在ZK节点挂得太多,只剩一半或不到一半节点能工做,集群才失效。因此

  • 3个节点的cluster能够挂掉1个节点(leader能够获得2票>1.5)

  • 2个节点的cluster就不能挂掉任何1个节点了(leader能够获得1票<=1)

22.zookeeper负载均衡和nginx负载均衡区别

zk的负载均衡是能够调控,nginx只是能调权重,其余须要可控的都须要本身写插件;可是nginx的吞吐量比zk大不少,应该说按业务选择用哪一种方式。

23.zookeeper watch机制

Watch机制官方声明:一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。

Zookeeper机制的特色:

一、一次性触发数据发生改变时,一个watcher event会被发送到client,可是client只会收到一次这样的信息。

二、watcher event异步发送watcher的通知事件从server发送到client是异步的,这就存在一个问题,不一样的客户端和服务器之间经过socket进行通讯,因为网络延迟或其余因素致使客户端在不通的时刻监听到事件,因为Zookeeper自己提供了ordering guarantee,即客户端监听事件后,才会感知它所监视znode发生了变化。因此咱们使用Zookeeper不能指望可以监控到节点每次的变化。Zookeeper只能保证最终的一致性,而没法保证强一致性。

三、数据监视Zookeeper有数据监视和子数据监视getdata() and exists()设置数据监视,getchildren()设置了子节点监视。

四、注册watcher getData、exists、getChildren

五、触发watcher create、delete、setData

六、setData()会触发znode上设置的data watch(若是set成功的话)。一个成功的create() 操做会触发被建立的znode上的数据watch,以及其父节点上的child watch。而一个成功的delete()操做将会同时触发一个znode的data watch和child watch(由于这样就没有子节点了),同时也会触发其父节点的child watch。

七、当一个客户端链接到一个新的服务器上时,watch将会被以任意会话事件触发。当与一个服务器失去链接的时候,是没法接收到watch的。而当client从新链接时,若是须要的话,全部先前注册过的watch,都会被从新注册。一般这是彻底透明的。只有在一个特殊状况下,watch可能会丢失:对于一个未建立的znode的exist watch,若是在客户端断开链接期间被建立了,而且随后在客户端链接上以前又删除了,这种状况下,这个watch事件可能会被丢失。

八、Watch是轻量级的,其实就是本地JVM的Callback,服务器端只是存了是否有设置了Watcher的布尔类型


读者福利:

要去面试光会一个知识点的题目那确定是不行的哦,必定要雨露均沾,因此给你们整理了一套,是一套哦,分专题的Java面试题,这份面试文档资料分享给你们。

领取方式:关注个人工种号 Java周某人

708cf88526a64308ae02083fc5dd8e76