ZooKeeper面试题 持续更新

ZooKeeper面试题


ZooKeeper文件系统

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


四种类型的znode

1.持久化节点
2.临时节点
3.持久化顺序节点
4.临时顺序节点


Zookeeper 特性

  • 顺序一致性
  • 原子性
  • 单一视图
  • 可靠性
  • 实时性(最终一致性)

客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机器来处理。
对于写请求,这些请求会同时发给其他zookeeper机器并且达成一致后,请求才会返回成功。因此,随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降。

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


Zookeeper通知机制

ZooKeeper的watcher机制,当ZNode的发生节点删除添加的操作或者节点内容发生改变,子节点的操作等,监听的Client会收到通知,然后我们可以在程序中进行自己进行处理


应用场景

1、命名服务
2、配置管理
3、集群管理
4、分布式锁
5、队列管理


命名服务

命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径,即是唯一的路径,这个路径就可以作为一个名字,指向集群中的集群,提供的服务的地址,或者一个远程的对象等等。

也就是我们常说的注册中心,进行服务的发布与消费,通过ZooKeeper协议进行服务的注册,将地址作为内容放到临时结点上,然后消费者可以通过ZooKeeper暴露出来的地址访问指定的服务名称获得服务的地址,然后服务间进行通信即可,与注册中心就无关了,一旦地址发生修改,ZooKeeper也会通过Watcher机制通知消费方修改地址,而且集群环境下只需要添加多个地址,然后再消费方程序中进行负载均衡算法的实现即可;


集群管理

所谓集群管理无在乎两点:是否有机器退出和加入、选举master。
对于第一点,所有机器约定在父目录下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。
新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了,对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

集群的管理主要有两点,机器的加入与退出,Master的选举
对于第一点我们可以让所有机器约好在同一个父节点下面创建临时节点,然后都监听父节点的节点变化,一旦服务宕机,或者什么其他情况,临时节点创建或者消失就会被集群中其他的机器收到通知,因此可以实现集群中机器的加入和退出对所有的成员来说是可知的;而Master的选举我们可以通过顺序节点,一旦Master宕机就选择集群中编号最小的机器作为Master其他机器跟着新的Master走就可以了


统一配置管理

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

将所有的配置文件都放在一个父节点下面,创建一个持久化节点,程序中只需要读取各自的配置文件信息即可,同时监听配置节点内容的修改,一旦内容修改就重启服务等系列的操作,实现了统一配置文件的处理


分布式锁

分为两种
1.保持独占锁
在业务逻辑之前,每次都去尝试创建一个临时节点,谁创建到了这个临时节点,谁就拿到了锁,进行相应的业务逻辑操作,在逻辑操作结束之后对节点进行销毁也就是释放锁即可’
2.顺序执行锁
在业务逻辑之前,都在一个已经存在的节点下面创建一个临时顺序节点,保证每次都是顺序编号最小的节点进行业务逻辑操作,当逻辑操作结束后,删除该节点,然后继续是顺序编号最小的节点进行业务逻辑操作,同样可以保证每次都是只有一个节点也就是一个线程在进行逻辑操作


队列管理

两种类型的队列:
1、同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
2、队列按照 FIFO 方式进行入队和出队操作。


获得分布式锁的流程

在获取分布式锁的时候在locker节点下创建临时顺序节点,释放锁的时候删除该临时节点。客户端调用createNode方法在locker下创建临时顺序节点,
然后调用getChildren(“locker”)来获取locker下面的所有子节点,注意此时不用设置任何Watcher。客户端获取到所有的子节点path之后,如果发现自己创建的节点在所有创建的子节点序号最小,那么就认为该客户端获取到了锁。如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁,此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时对其注册事件监听器。之后,让这个被关注的节点删除,则客户端的Watcher会收到相应通知,此时再次判断自己创建的节点是否是locker子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。当前这个过程中还需要许多的逻辑判断。


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

两种类型的队列:
1、同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
2、队列按照 FIFO 方式进行入队和出队操作。

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

第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。

  • 在特定的目录下创建PERSISTENT_SEQUENTIAL持久顺序节点,创建成功时Watcher通知等待的队列,队列删除序列号最小的节点用以消费。
  • 此场景下Zookeeper的znode用于消息存储,znode存储的数据就是消息队列中的消息内容,SEQUENTIAL序列号就是消息的编号,按序取出即可。
  • 由于创建的节点是持久化的,所以不必担心队列消息的丢失问题。

Zookeeper数据复制

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

  1. 容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作;
  2. 提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力;
  3. 提高性能:让客户端本地访问就近的节点,提高用户访问速度。

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

  1. 写主(WriteMaster) :对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离;
  2. 写任意(Write Any):对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。

对zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。


Zookeeper工作原理

  • Zookeeper 的核心是原子广播,这个机制保证了各个Server之间的同步。
  • 实现这个机制的协议叫做Zab协议。
  • Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。
  • 当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和
    leader的状态同步以后,恢复模式就结束了。
  • 状态同步保证了leader和Server具有相同的系统状态。此时系统的不可用的,所以ZooKeeper采用的是CP原则

Zookeeper 下 Server工作状态

每个Server在工作过程中有三种状态:

  1. looking:当前Server不知道leader是谁,正在搜寻
  2. leading:当前Server即为选举出来的leader
  3. following:leader已经选举出来,当前Server与之同步
  4. observing:观察者状态。表明当前服务器角色是Observer。

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

两段协议,首先会向其他的server发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行。

Zookeeper同步流程

  1. Leader等待server连接;
  2. Follower连接leader,将最大的zxid发送给leader;
  3. Leader根据follower的zxid确定同步点;
  4. 完成同步后通知follower 已经成为uptodate状态;
  5. .Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。

机器中为什么会有leader?

在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,于是就需要进行leader选举。


zk节点宕机如何处理?

Zookeeper本身也是集群,推荐配置不少于3个服务器。Zookeeper自身也要保证当一个节点宕机时,其他节点会继续提供服务。
如果是一个Follower宕机,还有2台服务器提供访问,因为Zookeeper上的数据是有多个副本的,数据并不会丢失;
如果是一个Leader宕机,Zookeeper会选举出新的Leader。
ZK集群的机制是只要超过半数的节点正常,集群就能正常提供服务。只有在ZK节点挂得太多,只剩一半或不到一半节点能工作,集群才失效。


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

zookeeper
  • 不存在单点问题,zab机制保证单点故障可重新选举一个leader
  • 只负责服务的注册与发现,不负责转发,减少一次数据交换(消费方与服务方直接通信)
  • 需要自己实现相应的负载均衡算法
nginx
  • 存在单点问题,单点负载高数据量大,需要通过KeepAlived+LVS备机实现高可用
  • 每次负载,都充当一次中间人转发角色,增加网络负载量(消费方与服务方间接通信)
  • 自带负载均衡算法

ZAB协议

ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。

ZAB协议包括两种基本的模式:崩溃恢复和消息广播。

当整个zookeeper集群刚刚启动或者Leader服务器宕机、重启或者网络故障导致不存在过半的服务器与Leader服务器保持正常通信时,所有进程(服务器)进入崩溃恢复模式,首先选举产生新的Leader服务器,然后集群中Follower服务器开始与新的Leader服务器进行数据同步,当集群中超过半数机器与该Leader服务器完成数据同步之后,退出恢复模式进入消息广播模式,Leader服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。


服务器角色

  • Leader
    事务请求的唯一调度和处理者,保证集群事务处理的顺序性
    集群内部各服务的调度者
  • Follower
    处理客户端的非事务请求,转发事务请求给Leader服务器
    参与事务请求Proposal的投票
    参与Leader选举投票
  • Observer
    3.3.0版本以后引入的一个服务器角色,在不影响集群事务处理能力的基础上提升集群的非事务处理能力

处理客户端的非事务请求,转发事务请求给Leader服务器
不参与任何形式的投票


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

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


zookeeper有几种部署方式

部署模式:单机模式、伪集群模式、集群模式。


Zookeeper对节点的watch监听通知是永久的吗?为什么不是永久的?

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

为什么不是永久的,举个例子,如果服务端变动频繁,而监听的客户端很多情况下,每次变动都要通知到所有的客户端,给网络和服务器造成很大压力。
一般是客户端执行getData(“/节点A”,true),如果节点A发生了变更或删除,客户端会得到它的watch事件,但是在之后节点A又发生了变更,而客户端又没有设置watch事件,就不再给客户端发送。
在实际应用中,很多情况下,我们的客户端不需要知道服务端的每一次变动,我只要最新的数据即可。


Zookeeper的java客户端都有哪些?

java客户端:zk自带的zkclient及Apache开源的Curator。


说几个zookeeper常用的命令。

常用命令:ls get set create delete等。


Zookeeper的典型应用场景

Zookeeper是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员可以使用它来进行分布式数据的发布和订阅。

通过对Zookeeper中丰富的数据节点进行交叉使用,配合Watcher事件通知机制,可以非常方便的构建一系列分布式应用中年都会涉及的核心功能,如:

  • 数据发布/订阅
  • 负载均衡
  • 命名服务
  • 分布式协调/通知
  • 集群管理
  • Master选举
  • 分布式锁
  • 分布式队列

会话管理

分桶策略:
将类似的会话放在同一区块中进行管理,以便于Zookeeper对会话进行不同区块的隔离处理以及同一区块的统一处理。

分配原则:每个会话的“下次超时时间点”(ExpirationTime)

计算公式:

ExpirationTime_ = currentTime + sessionTimeout
ExpirationTime = (ExpirationTime_ / ExpirationInrerval + 1) * ExpirationInterval , ExpirationInterval 是指 Zookeeper 会话超时检查时间间隔,默认 tickTime

你可能感兴趣的:(zookeeper)