简述

在分布式环境下,为了保障在同一时刻只能有一个客户端对指定的数据进行拜访,须要应用分布式锁技术。分布式锁实现次要以Zookeeper、Redis、MySQL这三种。

分布式锁的特点

  1. 互斥性:分布式锁须要保障在不同节点的不同线程的互斥。
  2. 可重入性:同一个节点上的同一个线程如果获取了锁之后那么也能够再次获取这个锁。
  3. 锁超时:和本地锁一样反对锁超时,避免死锁。
  4. 高效:高可用:加锁和解锁须要高效,同时也须要保障高可用避免分布式锁生效,能够减少降级。
  5. 反对阻塞和非阻塞:和ReentrantLock一样反对lock和trylock以及tryLock(long timeOut)。
  6. 反对偏心锁和非偏心锁(可选):偏心锁的意思是依照申请加锁的程序取得锁,非偏心锁就相同是无序的。这个一般来说实现的比拟少。

ZooKeeper分布式锁

利用ZooKeeper实现分布式锁,罕用的实现办法是,所有心愿取得锁的客户端都须要执行以下操作:

  1. 客户端连贯ZooKeeper,调用create()办法在指定的锁节点(如/lock)下创立一个长期程序节点。

    例如节点名为"zk",则第一个客户端创立的节点为“/lock/zk00000000”,第二个客户端创立的节点为"/lock/zk00000001"
  2. 客户端调用getChildren()办法查问锁节点/lock下的所有子节点列表,判断子节点列表中序号最小的子节点是否是本人创立的。如果是,则客户端取得锁,否则监听排在本人前一位的子节点的删除事件,若监听的子节点被删除,则反复执行此步骤,直至取得锁。
  3. 客户端执行业务代码。
  4. 客户端业务实现后,删除在ZooKeeper中对应的子节点以开释锁。

问题

一、上述第一步为什么要创立长期节点?

  1. 如果客户端A取得锁之后,客户端A所在的计算机宕机了,此时客户端A没有来得及被动删除子节点。如果创立的是永恒节点,锁将永远不会被开释,其余过程拿不到该资源。
  2. 长期节点的益处:只管客户端宕机了,然而ZooKeeper在肯定工夫内没有收到客户端的心跳则会认为回话生效,而后长期节点删除以开释锁。

二、未获取锁的客户端为什么要监听排在本人前一位的子节点的删除事件?

依照抢夺锁的规定,每一轮锁的抢夺取的都是序号最小的节点当序号最小的节点删除后,失常状况排在最小节点后一位的节点将取得锁。所以,客户端只须要监听本人前一位的节点即可,这样每当锁开释时,ZooKeeper只须要告诉一个客户端,从而节俭了网络带宽。若将监听事件设置在父节点/lock上,那么每次锁的开释将告诉所有客户端。如果客户端数量宏大,会导致ZooKeeper服务器必须解决的操作数量激增,减少了ZooKeeper服务器的压力,同时很容易产生网络阻塞

以上内容整顿自《Hadoop大数据技术开发实战》