zk的订阅会有丢消息的情况吗?

来源:9-2 Zookeeper实现配置中心的方案和代码解析

是个么有感情的杀手

2023-02-28

写回答

1回答

大能老师

2023-02-28


对于 ZooKeeper的订阅主要依赖于客户端 ZKClient 设置监听器,通过对节点设置Watch监听,节点的任何更新都会以通知的方式发送到Client端。

在这个过程中对于消息的可靠性可以分为两个部分:

 ZooKeeper 集群端:

在集群端,数据的一致性和集群的可用性由 ZooKeeper 自身的一些机制来进行保障;如“ZAB全称Zookeeper Atomic Broadcast(ZAB,Zookeeper原子消息广播协议)”保障数据之间的一致性。而在集群故障时使用“Leader选举算法”来保障集群的可用性。所以消息在集群端是可靠的。

数据订阅端:

而订阅的丢失一般出现在数据订阅的过程。*由于ZK的watch一次性注册原因,以及client断开连接到重新连接上这一段时间差,可能导致zookeeper客户端不能够接收到完所有的ZK事件。*

原因分析:

所 有的Zookeeper读操作,包括getData()、getChildren()和exists(),都有一个开关,可以在操作的同时再设置一个 watch。在ZooKeeper中,Watch是一个一次性触发器,会在被设置watch的数据发生变化的时候,发送给设置watch的客户端。 

watcher特性:

//img.mukewang.com/szimg/63fd9ba7096047fc13200446.jpg


 关于Watch实现

服务端

    zookeeper  server为每个本地client连接(不是session)维持一份watch表(map表),用于接收该client的watch请求,但不会把watch请求同步到其它节点(官方解释这样轻量化设计,好出多多…)

    每次更新某个数据时,就会触发watch通知,开始遍历本地client是否有对应watch请求事件,如果有,再判断该连接是否连接正常,连接正常则立马发通知,否则跳过当前client,遍历下一个。。

    Zks会启动独立线程,定时执行删除已断开连接的watcher,避免失活的watcher驻留消耗资源。

客户端

    根据应用请求watch类型,向当前连接的服务器申请watch请求,异步等待请求回复。若收到对应的watch回复,则执行对应的回调后,删除该watch请求。

   当连接断开时,则所有client的watcher会收到session断开事件执行回调,但其watch请求并没有并移除。


    当连接恢复时,无论是连接本地服务还是切换集群其它服务节点,本地client 所有 watcher请求会收到session恢复事件,回调再次被执行,请求不会被删除。接着,client的watch请求,会重新注册到连接服务器上,继续等待watch回调。

Watch特性要点

1. 仅支持单次触发。每次正常成功触发后(网络断开重连会触发额外增加断开和恢复两次回调),需要重新注册。

2. Watch本地保存。Watch请求不会同步到集群其它服务器。

3. 连接断开时, 会执行一次watch回调。

4. client中断期间,其watch事件会被原先的服务器直接丢弃,不会历史缓存。

5. 连接恢复时,会执行一次watch回调。

6. Client重连成功,会重新注册本地watch请求。


 事件丢失可能场景

  • 1. watch触发到完成再次注册期间,服务端对应节点发生变更的事件会丢失。

由于单次触发的特性,收到事件执行回调到再次注册watch时间差没法避免,通常的做法是先注册,再获取变更的数据,可以确保获取最新的变更不丢失,没法实现保证过程事件不丢失。


  •  2. 断网期间,服务端所发生的更新事件会全部丢失。

    根据zks的watch设计机制,其watch是本地的,实时的。当事件发生时,服务端watch事件会实时发送,且不缓存。链路正常就发送,不正常就跳过,简单粗暴,效率高。所以即使 session 没有过期,重连后会话标识仍然有效,但是断开这段时间的消息是没法重新发送的。


开发建议

1. 所有watch回调,若需要一直观察该节点变化,则先注册再获取数据,可以确保不丢失最新数据,能满足基本业务场景需求。

2. Zk不适合用于连续性状态同步的业务场景

3. 断网恢复时需要做一次主动同步。


更多内容可阅读:

  • 《从Paxos到Zookeeper : 分布式一致性原理与实践》

  • 《ZooKeeper : Distributed process coordination》

  • https://zookeeper.apache.org/doc/r3.5.9/zookeeperProgrammers.html#ch_zkWatches


0
0

Java分布式架构设计与开发实战

项目贯穿式讲解,真正将理论与实战相结合

325 学习 · 74 问题

查看课程