“无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。”。
目录
1. 请简述ZooKeeper 的选举机制
2. 客户端对ZooKeeper 的ServerList 的轮询机制
3. 客户端如何正确处理CONNECTIONLOSS( 连接断开) 和SESSIONEXPIRED(Session 过期)两类连接异常?
4. 一个客户端修改了某个节点的数据,其他客户端能够马上获取到这个最新数据吗?
1. 请简述ZooKeeper 的选举机制
假设有五台服务器组成的zookeeper 集群,它们的id 从1-5,同时它们都是最新启动的, 也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么。
- 服务器1 启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是LOOKING 状态。
- 服务器2 启动,它与最开始启动的服务器1 进行通信,互相交换自己的选举结果, 由于两者都没有历史数据,所以id 值较大的服务器2 胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1、2 还是继续保持LOOKING 状态。
- 服务器3 启动,根据前面的理论分析,服务器3 成为服务器1、2、3 中的Leader, 而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的Leader。
- 服务器4 启动,根据前面的分析,理论上服务器4 应该是服务器1、2、3、4 中最大的,但是由于前面已经有半数以上的服务器选举了服务器3,所以它成为Follower。
- 服务器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