小言_互联网的博客

大数据面试题(十)----Zookeeper 面试题

284人阅读  评论(0)

“无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。”。

大数据面试宝典目录,请点击

目录

1. 请简述ZooKeeper 的选举机制
2. 客户端对ZooKeeper 的ServerList 的轮询机制
3. 客户端如何正确处理CONNECTIONLOSS( 连接断开) 和SESSIONEXPIRED(Session 过期)两类连接异常?
4. 一个客户端修改了某个节点的数据,其他客户端能够马上获取到这个最新数据吗?


1. 请简述ZooKeeper 的选举机制

       假设有五台服务器组成的zookeeper 集群,它们的id 从1-5,同时它们都是最新启动的, 也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么。

  1. 服务器1 启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是LOOKING 状态。
  2. 服务器2 启动,它与最开始启动的服务器1 进行通信,互相交换自己的选举结果, 由于两者都没有历史数据,所以id 值较大的服务器2 胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1、2 还是继续保持LOOKING 状态。
  3. 服务器3 启动,根据前面的理论分析,服务器3 成为服务器1、2、3 中的Leader, 而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的Leader。
  4. 服务器4 启动,根据前面的分析,理论上服务器4 应该是服务器1、2、3、4 中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它成为Follower。
  5. 服务器5 启动,同4 一样成为Follower。注意,如果按照5,4,3,2,1 的顺序启动,那么5 将成为Leader,因为在满足半数条件后,ZooKeeper集群启动,5 的Id 最大,被选举为Leader。
2. 客户端对ZooKeeper 的ServerList 的轮询机制

       随机,客户端在初始化( new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) )的过程中,将所有Server 保存在一个List 中,然后随机打散,形成一个环。之后从0 号位开始一个一个使用。
       两个注意点:
       Server 地址能够重复配置,这样能够弥补客户端无法设置Server 权重的缺陷,但是也会加大风险。(比如: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181).
       如果客户端在进行Server 切换过程中耗时过长,那么将会收到SESSION_EXPIRED. 这也是上
面第1 点中的加大风险之处。

3. 客户端如何正确处理CONNECTIONLOSS( 连接断开) 和SESSIONEXPIRED(Session 过期)两类连接异常?

       在ZooKeeper 中,服务器和客户端之间维持的是一个长连接,在SESSION_TIMEOUT 时间内,服务器会确定客户端是否正常连接(客户端会定时向服务器发送heart_beat),服务器重置下次SESSION_TIMEOUT 时间。因此,在正常情况下,Session 一直有效,并且zk 集群所有机器上都保存这个Session 信息。在出现问题的情况下,客户端与服务器之间连接断了(客户端所连接的那台zk机器挂了,或是其它原因的网络闪断),这个时候客户端会主动在地址列表(初始化的时候传入构造方法的那个参数connectString)中选择新的地址进行连接。
       以上即为服务器与客户端之间维持长连接的过程,在这个过程中,用户可能会看到两类异常CONNECTIONLOSS(连接断开) 和SESSIONEXPIRED(Session 过期)。
       发生CONNECTIONLOSS 后,此时用户不需要关心我的会话是否可用,应用所要做的就是等待客户端帮我们自动连接上新的zk 机器,一旦成功连接上新的zk 机器后,确认之前的操作是否执行成功了。

4. 一个客户端修改了某个节点的数据,其他客户端能够马上获取到这个最新数据吗?

       ZooKeeper 不能确保任何客户端能够获取(即Read Request)到一样的数据,除非客户端自己要求, 方法是客户端在获取数据之前调用org.apache.zookeeper.AsyncCallbac k.VoidCallback,java.lang.Object) sync。
       通常情况下(这里所说的通常情况满足:1. 对获取的数据是否是最新版本不敏感,2. 一个客户端修改了数据,其它客户端是否需要立即能够获取最新数据),可以不关心这点。
       在其它情况下,最清晰的场景是这样:ZK 客户端A 对/my_test 的内容从v1->v2, 但是ZK 客户端B 对/my_test 的内容获取,依然得到的是v1. 请注意,这个是实际存在的现象,当然延时很短。解决的方法是客户端B 先调用sync(), 再调用getData()。


转载:https://blog.csdn.net/silentwolfyh/article/details/103929151
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场