当前位置: 首页 > 工具软件 > ZK > 使用案例 >

zk应用

阎涵容
2023-12-01

1.锁

前提:zk中有有序节点,临时节点在用户断开连接后,会自动失效,并且客户端可以watch机制,对一个节点目录进行操作的监视,一旦改目录有变化会通知客户端,

  • 排他锁:只有一个客户端能够获得锁

    获取锁:客户端通过create()在/exclusive/下创建lock临时节点/exclusive/lock节点,对于同一个节点,zk保证只有一个用户会创建成功,即得到了锁。其他未得到锁的客户端,watch 节点/exclusive

    释放锁:持有锁的客户端主动释放锁,其他等待锁的客户端会收到节点的变化,重新开始获取锁

  • 共享锁:类似读写锁

    获取锁:

    在需要获取共享锁的时候,客户端会在/shared_lock目录下创建有序临时节点(hostname-请求类型-序号)。例如如果是读请求,会创建192.168.0.1-R-001的节点。如果是写请求,会创建192.168.0.1-W-002的节点。

    是否获取到锁的判断:

    1. 创建完节点后,获取/shared_lock节点下的所有节点,并对该节点注册子节点变更的watcher监听

    1. 确定自己的节点序号在所有子节点中的顺序

    2. 对于读请求:如果没有比自己序号小的子节点,或者所有比自己序号小的子节点都是读请求,那么表明自己已经获取到了共享锁

      如果比自己序号小的子节点中有写请求,那么就需要进入等待

      对于写请求:

      如果自己不是序号最小的子节点,那么就需要进入等待。

      4. 接收到watcher通知后,重复1

    释放锁:

    与排他锁一致

     

    问题:共享锁中,未得到锁的客户端在watch通知后,都会获取所有节点信息,比较浪费。

    改进:

    watcher注册在获取锁的第3步中进行:

    读请求:向比自己序号小的最后一个写请求节点注册watcher

    写请求:向序号比自己小的最后一个节点注册watcher

    2.数据发布/订阅

    zk采用推拉式结合:

    1. 配置存储:在zk上,选取一个节点放置config文件

    2. 集群中没台机器启动初始化阶段,首先会去zk首次读取配置信息,同时会对放置配置文件的节点注册watcher,当以后配置发生变化,会通知客户端

    3. 配置文件变更后,zk会通知注册了wathcer的客户端,客户端重新获取配置信息

    note:

    • 如上节使用zookeeper来说,watcher机制并不能保证每一次配置的更改都推送给客户端,这种对于应用也是一件无法允许的事情

    • Watches通知是一次性的,必须重复注册.

    • 发生CONNECTIONLOSS之后,只要在session_timeout之内再次连接上(即不发生SESSIONEXPIRED),那么这个连接注册的watches依然在。

    • 节点数据的版本变化会触发NodeDataChanged,注意,这里特意说明了是版本变化。存在这样的情况,只要成功执行了setData()方法,无论内容是否和之前一致,都会触发NodeDataChanged。

    • 对某个节点注册了watch,但是节点被删除了,那么注册在这个节点上的watches都会被移除。

    • 同一个zk客户端对某一个节点注册相同的watch,只会收到一次通知。即 Watcher对象只会保存在客户端,不会传递到服务端。

    • 另外最主要一点就是zookeeper并不保证每次节点的变化都会通知到客户端,原因是因为当一次数据修改,通知客户端,客户端再次注册watch,在这个过程中,可能数据已经发生了许多次数据修改

    ####

 类似资料: