zookeeper典型应用场景之三:分布式锁

一、分布式锁介绍

        分布式锁主要用于在分布式环境中保护跨进程、跨主机、跨网络的共享资源实现互斥访问,以达到保证数据的一致性。所以“synchronized”、“ReentrantLock”是不能满足上述情况的.

二、架构介绍

         本章不考虑其他方式来实现分布式锁的机制,基于Zookeeper来实现分布式机制, 实现的架构图:

  blob.png

  原理的逻辑:

       1、在获取分布式锁的时候在locker节点下创建临时顺序节点,释放锁的时候删除该临时节点。客户端调用createNode方法在locker下创建临时顺序节点.

       2、然后调用getChildren(“locker”)来获取locker下面的所有子节点,注意此时不用设置任何Watcher。客户端获取到所有的子节点path之后,如果发现自己在之前创建的子节点序号最小,那么就认为该客户端获取到了锁。如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁;

        3、此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时对其注册事件监听器。之后,让这个被关注的节点删除,则客户端的Watcher会

       4、收到相应通知,此时再次判断自己创建的节点是否是locker子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。

 

资料参考:

     http://m.blog.csdn.net/article/details?id=51926396

基于Curator的实现:

   可重入锁Shared Reentrant Lock

      首先我们先看一个全局可重入的锁。 Shared意味着锁是全局可见的, 客户端都可以请求锁。 Reentrant和JDK的ReentrantLock类似, 意味着同一个客户端在拥有锁的同时,可以多次获取,不会被阻塞。

   它是由类InterProcessMutex来实现。

它的构造函数为:

    final InterProcessLock lock=new  InterProcessMutex(cf, "/super");

     lock.acquire(); //获取锁,提供了超时机制;

     lock.release(); //释放锁;

 不可重入锁Shared Lock

     这个锁和上面的相比,就是少了Reentrant的功能,也就意味着它不能在同一个线程中重入,意思就是acquire 多少次,就一定要release多少次,不然会一直阻塞.

     这个类是InterProcessSemaphoreMutex。

 可重入读写锁Shared Reentrant Read Write Lock

      类似JDK的ReentrantReadWriteLock.

    一个读写锁管理一对相关的锁。 一个负责读操作,另外一个负责写操作。 读操作在写锁没被使用时可同时由多个进程使用,而写锁使用时不允许读 (阻塞)。此锁是可重入的。一个拥有写锁的线程可重入读锁,但是读锁却不能进入写锁。

      这也意味着写锁可以降级成读锁, 比如请求写锁 —->读锁 ——>释放写锁。 从读锁升级成写锁是不成的。

    主要由两个类实现:

InterProcessReadWriteLock

InterProcessLock

信号量Shared Semaphore

   基于SharedCountReader;

多锁对象 Multi Shared Lock

       Multi Shared Lock是一个锁的容器。 当调用acquire, 所有的锁都会被acquire,如果请求失败,所有的锁都会被release。 同样调用release时所有的锁都被release。

    基本上,它就是组锁的代表,在它上面的请求释放操作都会传递给它包含的所有的锁。

主要涉及两个类:

InterProcessMultiLock

InterProcessLock

参考资料:

    http://www.aboutyun.com/thread-10725-1-1.html

发表评论