Zookeeper--分布式锁

分布式锁

  • 分布式锁是控制分布式系统之间同步访问资源的一种方式,如果不同系统是同一个系统的不同主机之间共享一个或一组资源,那么访问这些资源的时候,往往需要通过一些呼哧手段来防止彼此之间的干扰保证统一性,因此需要分布式锁。
排他锁
  • 简称X锁,或写锁,独占锁,是一种基本的锁类型,如果事务T1对数据对象Q1加上排他锁,那么整个加锁期间,只允许事务T1对Q1进行读,写操作,其他任何事务不能对Q1操作,直到T1释放
定义锁
  • Java开发中有两种方式,synchronized机制和JDK5中的ReentrantLock,然而,在Zookeeper中,没有类似于这样的API可以使用,Zookeeper通过数据节点表示一个锁,例如/exclusive_lock/lock节点被定义位一个锁
    Zookeeper--分布式锁
获取锁
  • 获取排他锁时,所有客户端调用create接口在/exclusive_lock节点下创建临时子节点/exclusive_lock/lock,Zookeeper保证只有一个客户端创建成功,我们认为这个创建成功的客户端就获取到锁,其他客户端需要在/exclusive_lock/lock节点上注册一个watcher监听,以便实时监听Lock节点变化
释放锁
  • /exclusive_lock/lock是一个临时节点,以下两种情况可认为释放
    • 当前获取锁的客户端机器宕机,ZooKeeper上的临时节点会被自动移除
    • 正常执行业务逻辑后,客户端自行删除临时节点
  • 无论上面两种哪一种,Zookeeper删除临时节点后/exclusive_lock/lock上注册Watcher监听的客户端都会收到Watcher通知,再次重新发起分布式锁的获取,重复以上流程,如下图所示排他锁流程
    Zookeeper--分布式锁
共享锁
  • 共享锁简称S锁,又称为读锁,同样是一种基本锁,如果T1对Q1加上共享锁,那么当前事务只能多Q1进行读,其他事务也只能对这个数据加共享锁,直到所有共享锁都释放。下面借助ZooKeeper来实现共享锁
定义锁
  • 与排他锁一样,同样通过ZooKeeper节点表示锁,类似/shared_lock/[Hostname]-请求类型-序号,的临时顺序节点,例如/shared_lock/129.168.1.1-R-0000001那么这个代表一个共享锁
    Zookeeper--分布式锁
获取锁
  • 客户端到/shared_lock这个节点下创建一个临时顺序节点,如果当前是读请求,那么就叉棍就如/shared_lock/129.168.1.1-R-0000001的节点,如果是写/shared_lock/129.168.1.1-W-0000001
判断读写顺序
  • 根据共享锁定义,不同事务可以同一时间多一个数据读,而更新只能单独进行,我们通过Zoo keep如下方式来进行:
    1. 创建节点后,获取/shared_lock节点下的所有子节点,并对该节点注册子节点变化的Watcher监听
    2. 确定字节节点序号在所有子节点中顺序
    3. 对于读请求:如果没有比字节序号小的子节点,或者是所有比字节序号小的子节点都是读,表明字节已经成功获取共享锁,同时开始读
    4. 对于写请求:如果子不是序号最小的子节点,进入等待
    5. 接收Watcher后,重复步骤1
释放锁
  • 与排他锁一致,删除释放
  • 用如下图解释

上一篇Zookeeper实践与应用-- Nginx负载均衡差异