关于zookeeper常见的8个面试问题

2,544 阅读9分钟

1. zookeeper是什么,都有哪些功能

Zookeeper是一个树形数据结构的高性能的分布式应用程序的协调服务。

在这里插入图片描述

拥有以下功能:

1、命名服务(naming): 是指通过指定的名字来获取资源或者服务的地址,提供者的信息。保证服务全局唯一。

2、配置管理(configuration management): 将配置信息保存在Zookeeper的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收Zookeeper的通知,然后从Zookeeper获取新的配置信息应用到系统中。

3、分布式锁(synchronization): 解决分布式资源访问冲突的问题。

4、集群管理(group services):

输入图片说明

多台 Server 组成一个服务集群,那么必须要一个“总管”知道当前集群中每台机器的服务状态,一旦有机器不能提供服务,集群中其它集群必须知道,从而做出调整重新分配服务策略。同样当增加集群的服务能力时,就会增加一台或多台 Server,同样也必须让“总管”知道。

2. zk 有几种部署模式

  1. 单机模式
  2. 集群模式(配置 zoo.cfg)
  3. 伪集群模式(一台服务器启动多个zookeeper实例运行)

3. zk 的通知机制

客户端端会对某个 znode 建立一个 watcher 事件,当该 znode 发生变化时,这些客户端会收到 zookeeper 的通知,然后客户端可以根据 znode 变化来做出业务上的改变。

4. zk 的分布式锁实现方式

在讲zk分布锁之前,先看下zookeeper中几个关于节点的有趣的性质:

  1. 有序节点:假如当前有一个父节点为/lock,我们可以在这个父节点下面创建子节点;zookeeper提供了一个可选的有序特性,例如我们可以创建子节点“/lock/node-”并且指明有序,那么zookeeper在生成子节点时会根据当前的子节点数量自动添加整数序号,也就是说如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,依次类推。
  2. 临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点。
  3. 事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端。当前zookeeper有如下四种事件: 1、节点创建;2、节点删除;3、节点数据修改;4、子节点变更。

下面描述使用zookeeper实现分布式锁的算法流程,假设锁空间的根节点为/lock:

  1. 客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推。
  2. 客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁,否则监听/lock的子节点变更消息,获得子节点变更通知后重复此步骤直至获得锁;
  3. 执行业务代码;
  4. 完成业务流程后,删除对应的子节点释放锁。

5. zk 采用的哪种分布式一致性协议? 还有哪些分布式一致性协议

zab协议是zookeeper专门设计的支持崩溃恢复的原子广播协议。目的是实现分布式zoopkeeper各个节点数据一致性。

zab协议约定zk节点有两种角色leader和follower,zk客户端会随机的链接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向 Leader 提交事务,Leader 接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。

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

整个 Zookeeper 就是在这两个模式之间切换。 简而言之,当 Leader 服务可以正常使用,就进入消息广播模式,当 Leader 不可用时,则进入崩溃恢复模式。

以上其实大致经历了三个步骤:

  1. 崩溃恢复:主要就是Leader选举过程。
  2. 数据同步:Leader服务器与其他服务器进行数据同步。
  3. 消息广播:Leader服务器将数据发送给其他服务器。

支持崩溃恢复后数据准确性的就是数据同步了,数据同步基于事务的 ZXID 的唯一性来保证。通过 + 1 操作可以辨别事务的先后顺序。

ZAD和Paxos算法的联系和区别

共同点:

  1. 两者都存在一个类似于Leader进程的角色,由其负责协调多个Follow进程的运行。
  2. Leader进程都会等待超过半数的Follower做出正确的反馈后,才会将一个提案进行提交。
  3. 在ZAB协议中,每个Proposal中都包含了一个epoch值,用来代表当前Leader周期,在Paxos算法中,同样存在这样一个标识,只是名字变成了Ballot。 不同点:

Paxos算法中,一个新的选举产生的主进程会进行两个阶段的工作

  1. 读阶段,新的主进程会通过和所有其他进程进行通信的方式来搜集上一个主进程提出的提案,并将它们提交。
  2. 写阶段,当前主进程开始提出它自己的提案。
  3. ZAB在Paxos基础上额外添加一个同步阶段。同步阶段之前,ZAB协议存在一个和Paxos读阶段类似的发现(Discovery)阶段

同步阶段中,新的Leader会确保存在过半的Follower已经提交了之前Leader周期中的所有事务Proposal

  • 发现阶段的存在,确保所有进程都已经完成对之前所有事物Proposal的提交
  • ZAB协议主要用于构建一个高可用的分布式数据主备系统,例如ZooKeeper,Paxos算法则是用于构建一个分布式的一致性状态机系统

6. zk 是怎样保证主从节点的状态同步

Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。

恢复模式:当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。

因此,选主得到的leader保证了同步状态的进行,状态同步又保证了leader和Server具有相同的系统状态,当leader失去主权后可以在其他follower中选主新的leader。

7. 集群中为什么要有主节点

在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行,

其他的机器可以共享这个结果,这样可以大大减少重复计算,提高性能,所以就需要主节点

8. leader 选举过程

有两种情况会发起Leader选举:

  1. 服务器启动的时候
  2. 服务器运行的时候当Leader宕机

在讲解流程之前,先说明一下选举流程中涉及到的角色:

  • LOOKING:寻找Leader状态,处于该状态需要进入选举流程(只有该节点才可以投票)
  • LEADING:领导者状态,处于该状态的节点说明是角色已经是Leader
  • FOLLOWING:跟随者状态,表示Leader已经选举出来,当前节点角色是follower
  • OBSERVER:观察者状态,表明当前节点角色是observer(该节点不参与竞选)

三个核心选举原则:

  1. Zookeeper集群中只有超过半数以上的服务器启动,集群才能正常工作;
  2. 在集群正常工作之前,myid小的服务器给myid大的服务器投票,直到集群正常工作,选出Leader;
  3. 选出Leader之后,之前的服务器状态由Looking改变为Following,以后的服务器都是Follower。

下面以一个简单的例子来说明整个选举的过程:

假设有五台服务器组成的Zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。

在这里插入图片描述

假设这些服务器从id1-5,依序启动:

因为一共5台服务器,只有超过半数以上,即最少启动3台服务器,集群才能正常工作。

(1)服务器1启动,发起一次选举。

服务器1投自己一票。此时服务器1票数一票,不够半数以上(3票),选举无法完成;

服务器1状态保持为LOOKING;

(2)服务器2启动,再发起一次选举。

服务器1和2分别投自己一票,此时服务器1发现服务器2的id比自己大,更改选票投给服务器2;

此时服务器1票数0票,服务器2票数2票,不够半数以上(3票),选举无法完成;

服务器1,2状态保持LOOKING;

(3)服务器3启动,发起一次选举。

与上面过程一样,服务器1和2先投自己一票,然后因为服务器3id最大,两者更改选票投给为服务器3;

此次投票结果:服务器1为0票,服务器2为0票,服务器3为3票。此时服务器3的票数已经超过半数(3票),服务器3当选Leader。

服务器1,2更改状态为FOLLOWING,服务器3更改状态为LEADING;

(4)服务器4启动,发起一次选举。

此时服务器1,2,3已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器3为3票,服务器4为1票。

此时服务器4服从多数,更改选票信息为服务器3;

服务器4并更改状态为FOLLOWING;

(5)服务器5启动,同4一样投票给3,此时服务器3一共5票,服务器5为0票;

服务器5并更改状态为FOLLOWING;

(6)选举结果

最终Leader是服务器3,状态为LEADING;

其余服务器是Follower,状态为FOLLOWING。