简述
在分布式环境下,为了保障在同一时刻 只能有一个客户端 对指定的数据进行拜访,须要应用分布式锁技术。分布式锁实现次要以 Zookeeper、Redis、MySQL 这三种。
分布式锁的特点
- 互斥性:分布式锁须要保障在不同节点的不同线程的互斥。
- 可重入性:同一个节点上的同一个线程如果获取了锁之后那么也能够再次获取这个锁。
- 锁超时:和本地锁一样反对锁超时,避免死锁。
- 高效:高可用: 加锁和解锁须要高效,同时也须要保障高可用避免分布式锁生效,能够减少降级。
- 反对阻塞和非阻塞:和 ReentrantLock 一样反对 lock 和 trylock 以及 tryLock(long timeOut)。
- 反对偏心锁和非偏心锁(可选):偏心锁的意思是依照申请加锁的程序取得锁,非偏心锁就相同是无序的。这个一般来说实现的比拟少。
ZooKeeper 分布式锁
利用 ZooKeeper 实现分布式锁,罕用的实现办法是,所有心愿取得锁的客户端都须要执行以下操作:
-
客户端连贯 ZooKeeper,调用
create()
办法在指定的锁节点(如 /lock)下创立一个长期程序节点。例如节点名为 ”zk”,则第一个客户端创立的节点为“/lock/zk00000000”,第二个客户端创立的节点为 ”/lock/zk00000001″
- 客户端调用
getChildren()
办法查问锁节点 /lock 下的所有子节点列表,判断子节点列表中序号最小的子节点是否是本人创立的。如果是,则客户端取得锁,否则监听排在本人前一位的子节点的删除事件,若监听的子节点被删除,则反复执行此步骤,直至取得锁。 - 客户端执行业务代码。
- 客户端业务实现后,删除在 ZooKeeper 中对应的子节点以开释锁。
问题
一、上述第一步为什么要创立长期节点?
- 如果客户端 A 取得锁之后,客户端 A 所在的计算机宕机了,此时客户端 A 没有来得及被动删除子节点。如果创立的是永恒节点,锁将永远不会被开释,其余过程拿不到该资源。
- 长期节点的益处:只管客户端宕机了,然而 ZooKeeper 在肯定工夫内没有收到客户端的心跳则会认为回话生效,而后长期节点删除以开释锁。
二、未获取锁的客户端为什么要监听排在本人前一位的子节点的删除事件?
依照抢夺锁的规定,每一轮锁的抢夺取的都是序号最小的节点 , 当序号最小的节点删除后,失常状况排在最小节点后一位的节点将取得锁 。所以,客户端只须要监听本人前一位的节点即可,这样每当锁开释时,ZooKeeper 只须要告诉一个客户端,从而节俭了网络带宽。若将监听事件设置在父节点 /lock 上, 那么每次锁的开释将告诉所有客户端 。如果客户端数量宏大,会导致 ZooKeeper 服务器必须解决的操作数量激增, 减少了 ZooKeeper 服务器的压力,同时很容易产生网络阻塞。
以上内容整顿自《Hadoop 大数据技术开发实战》