ZooKeeper完全解析(六) 使用ZooKeeper实现分布式锁之实现原理

  在上一篇中,我们讲了使用ZooKeeper来实现分布式作业调度系统的原理与实现,链接为 ZooKeeper完全解析(四) 使用ZooKeeper实现分布式作业调度系统之实现原理  ZooKeeper完全解析(五) 使用ZooKeeper实现分布式作业调度系统之Java实现  这一节我们讲一下ZooKeeper实现分布式锁的原理。

一、使用Redis实现分布式锁的原理以及对应缺陷:

  在讲解ZooKeeper实现分布式锁的原理之前,我们先回顾一下Redis来实现分布式锁的原理:

  我们在获取锁的时候给一个key setNX一个value,如果setNX成功,那么说明我们拿到了分布式锁,如果没有set成功,那么说明没有拿到分布式锁,系统需要循环去setNX,如果setNX成功,那么说明拿到了。

  之前写过相关的博客,链接为 分布式锁的原理与实现 一、分布式锁的原理 ,分布式锁的原理与实现 二、分布式锁的基础实现 。

  那么,这样实现有什么问题呢?首先一点就是很难实现排队机制,即先入先出,即先开始竞争获取锁的,应该先拿到锁,而上述是每个线程都在循环setNX,很可以出现后来的竞争获取锁的,先拿到了锁。其次,如果多个线程都在一直setNX,对系统也是一个负担。

 

二、使用ZooKeeper实现分布式锁的原理:

  ZooKeeper在设置节点的时候,允许我们来设置一个顺序节点,而且我们能监听某一个节点的删除状态以及数据更新状态。这就为我们事先分布式锁提供了基础。

  比如我们要抢购一个商品,那么抢购这个商品的时候需要使用分布式锁,而且我们也想实现先抢的人先获取到分布式锁,就可以这样:

  1、首先创建 /lock 节点,如果创建成功则不管, 然后创建 顺序-临时节点 /lock/goods 

  2、创建成功后,遍历 /lock 节点的子节点,如果发现自己的节点是顺序中的第一个,那么说明拿到了分布式锁,开始执行任务,执行完成后删除自己的子节点。如果不是顺序中的第一个,执行第3步

  3、获取到子节点中在自己创建的节点的前一个节点,监听其状态变化,当监听到前一个节点删除的时候,重新进行第2步。

  比如现在有4个线程 A、B、C、D 来获取锁,分别获取到  /lock/goods0000000000 、/lock/goods0000000001 、/lock/goods0000000002、 /lock/goods0000000003 。那么A开始执行, B监听A,C监听B,D监听C。这时候,如果A执行完成,删除了 /lock/goods0000000000 节点,那么B监听到A执行完成,开始执行。

  有人可能说,如果C宕机了呢?如果C宕机了,那其创建的顺序-临时节点则会消失,D重走了第2步,则会监听B。

 

三、实现代码:

  在下一篇中,我们将会使用Java代码来实现ZooKeeper分布式锁:ZooKeeper完全解析(七) 使用ZooKeeper实现分布式锁之Java实现

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值