监听与特性 - Zookeeper 面试题及答案
8.说说Wather监听机制和它的原理?

具体的步骤如下:
- 服务注册:Provider 启动时,会向 zookeeper 服务端注册服务信息,也就是创建一个节点。
- 服务发现:Consumer 启动时,根据自身配置的依赖服务信息,向 zookeeper 服务端获取注册的服务信息并设置 watch 监听,获取到注册的服务信息之后,将服务提供者的信息缓存在本地,并进行服务的调用。
- 服务通知:一旦服务提供者因某种原因宕机不再提供服务之后,客户端与 zookeeper 服务端断开连接,zookeeper 服务端上服务提供者对应服务节点会被删除,随后 zookeeper 服务端会异步向所有注册了该服务,且设置了 watch 监听的服务消费者发出节点被删除的通知,消费者根据收到的通知拉取最新服务列表,更新本地缓存的服务列表。
简单的理解就是 client 会对某个 znode 注册一个 watcher 事件,当该 znode 发生变化时,这些 client 会收到 ZooKeeper 的通知。
四个特性:
- 一次性:一旦一个Wather触发之后,Zookeeper就会将它从存储中移除,如果还要继续监听这个节点,就需要我们在客户端的监听回调中,再次对节点的监听watch事件设置为True。否则客户端只能接收到一次该节点的变更通知
- 客户端串行:客户端的Wather回调处理是串行同步的过程,不要因为一个Wather的逻辑阻塞整个客户端
- 轻量:Wather通知的单位是WathedEvent,只包含通知状态、事件类型和节点路径,不包含具体的事件内容,具体的时间内容需要客户端主动去重新获取数据
- 异步: Zookeeper服务器发送watcher的通知事件到客户端是异步的,不能期望能够监控到节点每次的变化,Zookeeper只能保证最终的一致性,而无法保证强一致性。
9.Zookeeper有哪些特性呢?

- 顺序一致性:leader会根据请求顺序生成 ZXID 来严格保证请求顺序的下发执行。
- 原子性:所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,要么成功,要么就失败。
- 单一视图:无论客户端连到哪一个 ZooKeeper 服务器上,看到的数据都是一致的。
- 可靠性:一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来。
- 实时性:Zookeeper 仅仅能保证在段时间内客户端最终一定能够从服务端上读取到最新的数据状态。
10.Zookeeper 如何识别请求的先后顺序?

Leader 收到请求之后,会将每个请求分配一个全局唯一递增的事务ID:zxid,然后把请求放入到一个 FIFO 的队列中,之后就会按照 FIFO 的策略发送给所有的 Follower。
点击这里👇🏻:复杂的微服务系统、商城系统、代码生成工具实战、秒杀系统、常用demo系统、AI项目等等,手把手从0~1,带你开发完整的项目,这里能够获取项目源代码、开发教程、部署文档和问题答疑
11.选举 leader 后是怎么进行数据同步的

前面提到写数据是由 leader 负责的,而 leader 会将每个请求分配一个 ZXID,放入一个队列中,依次执行,每次 leader 执行完一个请求后,会记录下执行的这个 ZXID。
我们将这个队列中最大的 ZXID 称为 maxZXID,最小的 ZXID 称为 minZXID。
将 Observer 和 follower 中最新的 ZXID 称为lastSyncZXID
proposal : l其实就是将请求中的一些信息如请求头,请求体以及 ZXID 等信息封装到 proposal对象当中
- 1.差异化同步
- 1).leader 向 Observer 和 follower 发送 DIFF 指令,之后就开始差异化同步
- 2).然后把差异数据 提议 proposal 发送给 Observer 和 follower , Observer 和 follower 返回ACK表示已经完成了同步
- 3).只要集群中过半的 Observer 和 follower 响应了 ACK 就发送一个 UPTODATE 命令
- 4).leader 返回 ACK,同步流程结束
- 触发条件:minZXID < lastSyncZXID < maxZXID
- 同步过程:
- 2.回滚同步
- 1).直接回滚到 maxZXID
- 触发条件 maxZXID < lastSyncZXID
- 举个例子:a,b,c三台服务服务器 a是leader,此时队列里面最大的 ZXID 为100,a 收到请求,该 ZXID 为101,还没来得及发送同步数据 a 就挂了,b 变为leader,然后 a 恢复了,此时就需要 a 先将之前 ZXID 为101的数据回滚
- 同步过程:
- 3.回滚+差异化同步
- 1).Observer 和 follower 将数据回滚
- 2).进行差异化同步
- 触发条件:如果Leader刚生成一个proposal,还没有来得及发送出去,此时Leader宕机,重新选举之后作为Follower,但是新的Leader没有这个proposal数据
- 举个例子:a,b,c三台服务服务器 a是leader,此时队列里面最大的 ZXID 为100,a 收到请求,该 ZXID 为101,还没来得及发送同步数据 a 就挂了,b 变为leader,b 又处理了3个请求,则 b 队列中最大的 ZXID 为103,然后 a 恢复了,此时就需要 a 先将之前 ZXID 为101的数据回滚,再进行同步
- 同步过程:
- 4.全量同步
- 1).lastSyncZXID < minZXID
- 2).Leader服务器上没有缓存队列,并且lastSyncZXID!=maxZXID
- 触发条件
- 同步过程:leader 向 Observer 和 follower 发送SNAP命令,进行数据全量同步
12.Zookeeper 会有数据不一致的情况发生吗?
还是会有的,因为 Zookeeper 采用的是过半写机制,意味着3台服务器只要有两台写成功就代表整个集群写成功,如果刚好有请求打在这台还未写的服务器上就查询不到该数据,就会有数据不一致的情况产生。
作者:moon聊技术
来源:https://cloud.tencent.com/developer/article/1853415
最近建一些几十个工作内推群,各大城市都有,群里目前已经收集了很多内推岗位,大厂、中厂、小厂、外包都有。 欢迎HR、开发、测试、运维和产品加入。

扫描下方微信,备注:网站+所在城市,即可拉你进工作内推群。
