Skip to content

Zookeper面试题

Updated: at 12:12 PM

Zookeper

1. Zookeper应用场景

1.1. Zookeper的典型应用场景

ZooKeeper使用场景总结-CSDN博客

1.1.1. 配置中心

  1. 将服务的信息配置到Zookeper的一个节点上
  2. 应用对该节点注册一个watcher,一旦更新就去该节点上获取最新的配置数据。

1.1.2. 命名服务

  1. 路径代表地址,比如/myMachine/name
  2. 节点的数据就是多个节点ip

1.1.3. 集群管理

  1. 节点信息作为Zookeper的临时节点,通过临时节点监控服务的存活状态
  2. Zookeper的watcher机制接收控制信息

1.1.4. 服务注册中心&复杂均衡

  1. 对某一个服务注册一个持久节点作作为对外提供服务的名称
  2. 服务提供者启动后将自己挂在对应服务的下面,创建的是临时节点,保存自己的调用信息
  3. 消费者调用服务的时候,去对应的服务下面查出所有的provider。并采用watcher监听服务提供者们的变化。
  4. 消费者根据服务注册表,用本地负载均衡算法去访问对应的服务

1.1.5. 集群master的选举

  1. 即从一个集群多个server中选举中一个master完成某个任务

  2. 采用分布式锁容易实现这个,但是无法检测到server的存活状态。于是使用Zookeper的唯一性(同一路径的节点是唯一的)机制和watcher机制(宕机节点消失,watcher检测到后重新选举)即可。

1.1.6. 分布式锁

  1. 在一个指定目录下,客户端进行加锁就是加一个顺序临时节点
  2. 如果是序号最小的,则获取锁成功。如果不是序号最小的,watcher它序号的上一个节点。
  3. 释放节点的时候会被下一个节点watcher,下一个节点继续获取锁(判断是否是序号最小)

Zookeper支持的分布式锁的种类有排他可重入锁,排他不可重入锁,读写锁,共享锁等

1.1.7. 分布式队列

与分布式锁类似,因为分布式锁本身也是一个阻塞队列实现的

2. Zookeper的实现

2.1. Zookeper的数据结构

  1. ZK中数据是以目录结构的形式存储的。其中一个存储数据的节点都叫Znode,每个Znode都有唯一路径表示。
  2. 每一个节点可能有子节点(临时节点除外)。节点中可以存储数据和状态,
  3. 每个Znode可以配置监视器(watcher),用于监听节点中的数据变化。
  4. 节点只支持一次性独写

2.2. Zookeper的节点

2.2.1. 临时节点

临时节点的生命周期和客户端会话绑定

2.2.2. 持久节点

一直存在,直到手动删除

2.2.3. 临时顺序节点

临时节点的生命周期和客户端会话绑定,并且会自动加上编号

2.2.4. 持久顺序节点

生命周期永久,并且会自动加上编号。

2.3. Zookeper实现的分布式锁

  1. 锁可以释放:因为是临时节点
  2. 阻塞锁:Zookeper实现阻塞的锁,watcher机制监听前一个节点来唤醒。
  3. 可重入:每次加入新的lock节点之后,判断序号最小的和当前新加的lock的信息是否是一样的,如果是则代表重入
  4. 单点问题:Zookeper搭集群可以解决单点有效问题

缺点:没有缓存性能高

2.4. 📣Zookeper的watch机制是如何工作的?

客户端ZkWatcherManager,服务端watchManage

  1. ZkWatchManager创建watcher并注册到客户端,客户端将watcher信息发给服务端
  2. Zookeper服务端收到客户端发送的watcher信息后,会将该watcher信息交给watchManager处理。watchManager会将该watcher注册到对应的znode节点上,并将watcher相关的信息保存到内存中
  3. 当znode发生变化,watchServer会通知zookeper server
  4. zookeeper Server会根据变化的类型通知客户端
  5. zkWatcherManager会根据watcher的类型触发相应的事件处理方法

2.5. Zookeper如何保证创建的节点是唯一的?

  1. 写请求都由Leader写
  2. synchronized + concurrentHashMap

具体的,创建节点的时候先synchronized将父节点锁住,然后判断该节点是否存在,不存在就用concurrentHashMap的线程安全方法put添加node

2.6. Zookeper客户端的命令

2.6.1. ls

因为zookeper是树状的,所以可以查看该层有哪些节点

ls / 

查看根节点

ls /dubbo 

查看dubbo根节点下面有哪些节点

ls /dubbo/config

同理

ls -s /dubbo

查看节点详细信息

2.6.2. create

  1. 创建持久化节点
create /appl itheima

创建/appl持久化节点,数据为itheima

  1. 创建临时节点
create -e /appl itheima

创建/appl临时节点,数据为itheima

  1. 创建持久化顺序节点
create -s /appl

创建的节点会自动加编号

  1. 创建临时顺序节点
create -es /appl

2.6.3. get

获取 /appl 节点

get /appl

2.6.4. set

设置 /appl 的值为itcast

set /appl itcast

2.6.5. delete

delete 删除 /appl/p1

delete /appl/p1

3. Zookeper高可用

3.1. Zookeper集群中的角色有哪些?有什么区别?

3.1.1. 领导者Leader

  1. 事务读和写请求的处理
  2. 负责投票的发起和决议

3.1.2. 跟随者Follower

  1. 接受事务写请求转发给Leader,返回请求结果
  2. 为客户端提供读服务
  3. 用于客户端请求并响应客户端的返回结果

3.1.3. 观察者Observer

  1. 可以客户端连接,写请求转发给leader
  2. 不参与投票,只同步leader的状态
  3. observer的目的是为了扩展系统,提高系统读取速度

3.2. Zookeper是CP的还是AP的?

CP的,会丢掉可用性A

遇到极端情况,比如集群中网络分割的故障,Zookeper会将它们都从自己的管理范围中删除出去,外界就不能访问这些节点了

3.3. Zookeper的选举机制是怎样的?

可以参考raft算法的投票选举思想

  1. 在启动阶段或者Leader失效的时候,会发起Leader选举
  2. 选举就是根据每个节点的zxid比较,如果别人zxid >=自己的就投给它一票
  3. 选举可能分多轮,如果一轮选不出来(两个票数相同),则重新选举
  4. Leader选出来以后同步给集群其他节点

3.4. 什么是脑裂?如何解决?

3.4.1. 脑裂出现的原因?

  1. Zookeper集群中的某些节点无法与其他节点通信时,就会出现网络分区现象。这时,会出现多个主节点。
  2. 主节点宕机,集群会选出新的主节点。等宕机的主节点恢复后,就会出现两个主节点。

3.4.2. 脑裂的解决?

  1. 自动恢复。一般会重新选取主节点,并同步给集群。
  2. 手动恢复:比较复杂

3.4.3. 避免脑裂产生?

  1. 通过Zookeper的watch机制监听节点的变化,及时发现异常情况
  2. 设置合适的选举超时时间,设置合适的节点数量