7、zk典型应用场景之分布式锁
分布式锁: 分布式锁是控制分布式系统之间同步访问共享资源的一种方式,如果不同的系统化或者同一个系统的不同主机之间共享一个或者一组资源,那么在访问这些资源的时候,往往需要通过一些互斥手段防止彼此之间的干扰,以保证一致性,这种情况就需要使用分布式锁。
排他锁: 核心是如何保证当前有且仅有一个事务获取到锁,并且锁释放之后,所有正在等待获取锁的事务都能够被通知到。
定义和获取锁: 在zk中,通过一个数据节点来表示一个锁(因为在zk中数据节点是唯一的),zk会保证在所有客户端中,最终只有一个客户端能够创建一个节点成功,最终只有一个客户端能够创建成功,那么久可以认为这个客户端获得了锁。同时没有获取到锁的客户端就需要到相应节点上注册一个子节点变更的watcher监听,以便实时的监听lock节点的变更情况。
释放锁: 由于定义锁的节点是一个临时节点,因此存在两种情况释放锁1、当前获取锁的客户端机器发生宕机了。zk就会把该临时节点删除2、正常执行完业务逻辑,客户端会主动将自己创建的临时节点删除。而无论什么情况下面删除了节点,zk都会通知所有在该节点上注册了子节点变更watcher将的客户端。这些客户端在接收到通知后,会再次重新发起分布式锁获取,即重复“获取锁过程”。
(获取锁和释放锁流程)
共享锁: 称读锁。如果事务T对数据对象O加了共享锁,那么当前的事务只能对O进行读取操作,其他事务也只能对这个数据对象加共享锁-直到该数据对象上的所有共享锁都被释放。
定义锁: 同样是使用zk上的数据节点来表示一个锁,是一个类似“/share_lock/[hostname]-请求类型-序号”的临时顺序节点。
获取锁: 在需要获取共享锁时候,所有客户端都会到/share_lock这个节点下面创建一个临时顺序节点,如果当前是读请求,那么就是例如/share_lock/192.168.0.1-R-0000000001的节点;如果是写请求,那么就会创建例如/share_lock/192.168.0.1-W-0000000001的节点。
判断读写顺序: 不同事务都可以同时对一个数据对象进行读写操作,而更新操作必须在当前没有任何事务进行读写操作的情况下面进行。基于这个原则可以通过下面四个步骤来确定分布式读写顺序:
释放锁: 和排他锁一样。
加锁情况:
(1)实现流程
(2)源码解读
1、InterProcessMutex构造函数
2、加锁
InterProcessMutex.class
3、锁的可重入性
4、抢夺锁
参考资料:
《从Paxos到Zookeeper 分布式一致性原理与实践》》
https://www.jianshu.com/p/6618471f6e75
https://juejin.im/post/5c01532ef265da61362232ed
2024-08-19 广告