Zookeeper面试题

1.Zookeeper是什么

Zookeeper是一种分布式协调服务,它在中间件处于鼻祖的地位,在很早分布式概念提出来的时候,Zookeeper里面就有一些非常精彩的设计,比如说分布式锁,集群选举,崩溃恢复,数据同步,以至于之后的很多中间件,比如说redis,dubbo的注册中心,kafka也需要用到zookeeper做协调。

2.在项目中用Zookeeper来干什么了

dubbo注册中心、分布式锁、统一配置管理等

统一配置管理:将配置信息写到一个ZK的Znode下,让客户端都监听这个Znode,一旦Znode的数据发生变化,就会通知监听他的所有的客户端。

  1. 分布式协调组件
    在这里插入图片描述

  2. 分布式锁

  3. 无状态化的实现
    在这里插入图片描述

3.Zookeeper的常用命令

#启动命令
#进入bin目录
./zkServer.sh start 启动zk服务器
./zkServer.sh stop 停止zk服务器
./zkServer.sh status 查看服务器的状态

./zkCli.sh  启动客户端连接zk服务器
./zkCli.sh -server 服务器IP地址   启动客户端连接指定的服务器
#zk客户端常用的命令
help 显示所有的操作命令

create path [Value]  创建节点  -e 创建临时节点 -s 创建节点名称带序号
delete path 删除节点
deleteall path 递归删除节点
set path value   设置节点具体的值
get path   获得节点的值  -s 附加次级信息
ls path    使用 ls 命令来查看当前 znode 的子节点
stat path 查看节点状态

get -w path  监听节点内容的变化
ls -w path     监听⽬录,创建和删除⼦节点会收到通知。⼦节点中新增节点不会收到通知
lw -R -w path    监听所有⼦节点中⼦节点的变化,但内容的变化不会收到通知

4.Zookeeper的持久化机制(对比Redis)

zk的数据是运行在内存中的,zk提供了两种持久化机制

  • 事务日志
    zk把执行的命令以日志形式保存在dataLogDir指定的路径中的文件中(没指定按dataDir指定的路径)
  • 数据快照
    zk每隔一段时间会做一次内存数据的快照,把该时刻的内存数据保存在快照文件中

zk同时使用两种形式的持久化,先恢复快照文件的数据到内存中,再用日志文件中数据做增量恢复,这样的恢复速度更快。
在这里插入图片描述

5.Zookeeper的监听机制

Zookeeper允许客户端向服务端中某个Znode注册一个Watcher,当这个Znode发生改变(setData,create,delte)时候,指定客户端就会接收到异步通知。

6.Zookeeper分布式锁的实现原理

Zookeeper如何上读锁

原理:前面只有读锁的时候才可以上读锁,也就是只要最小节点是读锁,那么后面肯定都是读锁不可能是写锁,就可以加读锁成功

  • 创建一个名称为read的临时序号节点,用于表示读锁
  • 获取zk中序号比自己小的所有节点
  • 判断最小节点是否是读锁,如果是就加锁成功
  • 否则就加锁失败,监听这个最小节点,当最小的节点发生变化时就会通知当前节点,然后再去获取比自己小的所有节点,判断最小节点是否是读锁,不断循环,直到最小的节点是读锁就加锁成功
    在这里插入图片描述

Zookeeper如何上写锁

原理:只要前面没有任何锁就可以加锁成功,也就是只要自己是最小节点就加锁成功

  • 创建一个名称为write的临时序号节点,用于表示写锁
  • 获取所有的子节点
  • 判断自己是否是最小的节点,如果是就加写锁成功
  • 否则加写锁失败,监听当前节点的上一个节点,如果上一个节点有变化就就会通知当前节点。然后再去获取所有子节点,判断自己是否是最小节点,不断的循环,直到自己是最小节点就加锁成功
    在这里插入图片描述

7.Zookeeper集群模型

zookeeper集群是一主多从的模型

节点分为三种角色:

  • leader:主要所有请求
  • follower: 只能处理读的请求,写请求转发给leader,参与选举
  • observer: 只能处理读的请求,不参与选举

节点的状态有四种

  • Looking :选举状态。
  • Following :Follower 节点(从节点)所处的状态。
  • Leading :Leader 节点(主节点)所处状态。
  • Observing:观察者节点所处的状态

8.Zookeepr的选举机制

全新集群启动选举规则:
(1)服务器1启动,发起一次选举。

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

服务器1状态保持为LOOKING;

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

服务器12分别投自己一票,然后彼此交换投票信息后,服务器1发现服务器2的id比自己大,更改选票投给服务器2;

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

服务器12状态保持LOOKING;

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

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

此次投票结果:服务器10票,服务器20票,服务器33票。此时服务器3的票数已经超过半数(3票),服务器3当选Leader。

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

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

此时服务器123已经不是LOOKING状态,不会更改选票信息。交换选票信息结果:服务器33票,服务器41票。

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

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

(5)服务器5启动,同4一样投票给3,此时服务器3一共5票,服务器5为0票; 服务器5并更改状态为FOLLOWING;

最终Leader是服务器3,状态为LEADING;
其余服务器是Follower,状态为FOLLOWING。

理论上是事务id大的胜出,但是全新的集群启动时事务id都是0,所以只比较服务器id,投票过半数时,服务器id大的胜出

崩溃恢复时的leader选举:

  • 逻辑时钟小的选举结果被忽略,重新投票
  • 统一逻辑时钟后,事务id大的胜出
  • 事务id相同的情况下,服务器id大的胜出

事务id:zxid越大,表示这个节点的数据越新
server id:就是我们配置集群的时候那个myid
逻辑时钟EPOCH:每次选举出leader时这个值就会+1,同一轮选举中,这个值是一致的

9.ZAB协议的特点

ZAB协议有如下特点:

  • follower节点上所有的写请求都转发给leader
  • 写操作严格有序
  • Zookeeper使用改编的两阶段提交协议来保证各个节点的事务一致性

正常的两阶段提交是
1.协调者询问所有参与者是否可以提交
2.参与者回复yes 或 or
3.当协调者收到所有参与者yes之后才会去执行commit,否则执行rollback。
4.参与者执行完成回复yes

改编的两阶段提交协议:超过半数的参与者回复yes,而不是所有参与者回复yes

10.ZAB协议是如何保证ZK各个节点数据一致性的

zookeeper集群的状态分为两种:正常状态和异常状态。也就是有leader(能提供服务)和没有leader(进入选举)。也就是说zab协议包含两种基本模式:消息广播崩溃恢复

消息广播(数据同步原理)
广播模式就是指zookeeper正常工作的模式。它是通过改编的两阶段提交协议保证各个节点的数据一致性的。

  1. leader从客户端或者follower那里收到一个写请求
  2. leader先把数据写到本地数据文件中,再以proposal的形式发送给所有follower的proposal队列中
  3. follower收到proposal后,也根据接收先后顺序将数据写到本地磁盘中,写入成功后发送ack给leader
  4. leader收到超过半数的ack消息后,leader会发送commit请求,同时自身完成事务的提交(将本地磁盘数据写到内存中)
  5. follower收到消息后也会将事务提交把数据写到内存中,最后反馈给客户端。
    在这里插入图片描述

崩溃恢复
一旦leader宕机就会进入崩溃恢复模式。崩溃恢复主要包括leader选举和数据恢复两部分。

根据两阶段提交模型,有可能leader宕机会带来数据不一致情况有两种

  • 如果事务没有发出去,所有follower都没有收到这个事务,leader宕机了
  • leader已经commit了,但是commit消息没发出去之前宕机了

ZAB 协议确保那些已经在 Leader 提交的事务最终会被所有服务器提交。
ZAB 协议确保丢弃那些只在 Leader 提出/复制,但没有提交的事务。

leader选举
follower会用最快的速度选举出一个新的leader。会根据每个follower节点的zxid来选择,谁的zxid最大,谁的数据最新,就会被选举为新的leader。如果zxid都一样,说明在leader故障之前,所有的follower节点数据完全一致,此时会选择myid最大的节点成为leader。

如果新leader选出来之后,原来的leader又恢复了,此时原来的leader会自动成为follower,之前的事务即使重新发送给新的leader,因为新的leader开启了新的纪元,而原先的leader中的zxid还是旧的纪元,自然会被丢弃。该节点的zxid也会更新成新的纪元。

数据恢复
场景:

  • 选举为新的leader后follower要跟leader之间进行同步
  • 或者某个follower宕机后,leader没法把数据同步给宕机的节点,就会造成数据不一致。所以为了解决这个问题,当节点启动时,第一件事就是找当前leader同步数据

步骤:

  1. 新的leader跟follower建立连接,follower给leader发送自己的zxid
  2. leader将自己的zxid和follower发送过来的zxid进行对比
  3. leader确定follower的数据同步点,就是两个zxid之间的数据需要同步
  4. follower开始同步数据,同步时不对外提供读写服务(保证CP)
  5. follower同步完成后,发送消息给leader
  6. leader修改当前follower的状态为update,这个时候follower就可以正常接受客户端的读写请求,但是写入请求会转发给leader
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值