简单说一下Zookeeper分布式锁

前言

实现分布式锁有很多方式,其中最常用的应该是Redis分布式锁和Zookeeper分布式锁。初识Zookeeper还是在学习SpringCloud微服务的时候,当时只是把它拿来做分布式配置中心和注册中心的,没想到它的应用场景还挺多的,如分布式锁、集群选举等等。今天简单了解了一下它的分布式锁的场景,这篇文章只是用来记录一下个人对Zookeeper分布式锁原理的简单理解。

Zookeeper的分布式锁的实现

唯一节点特性

Zookeeper分布式锁的实现是基于它的唯一节点特性来的。

唯一节点特性:多个应用程序去Zookeeper上创建同一节点时,只会有一个应用程序可以成功创建该节点。

具体实现方式

主要有两种方式实现:基于临时节点实现、基于临时顺序节点实现。从这两种方式可以看出,第二种实现方式是第一种方式的进阶版。因为第一种方式会产生惊群效应

基于临时节点实现

我们可以在多个线程去抢占锁资源时,只需要在指定节点上创建一个同名节点(如在/下面创建/LOCK节点),由于Zookeeper中节点的唯一特性,使得只会有一个线程成功创建/LOCK节点,剩下没有创建成功的用户就表示竞争锁失败。意思就是谁能创建这个节点,谁就获得锁。

这种方式虽然能达到目的,但是会出现一个问题,假设现在有非常多的节点(集群节点)需要等待获得锁,但是想要获得锁,也得等到创建这个/LOCK节点的集群节点把/LOCK节点删除之后才行,所以其它集群节点需要一直监听这个删除事件,一旦发现该/LOCK节点被删除就说明之前创建该/LOCK节点的集群节点已经释放了锁,那么此时剩下的集群节点会同时收到删除事件从而去竞争锁(创建/LOCK节点),这个过程就会产生惊群效应。

惊群效应:简单来说就是如果存在许多的客户端在等待获得锁,当成功获取到锁的进程释放该节点后,所有处于等待状态的客户端都会被唤醒,这个时候Zookeeper会在短时间内发送大量节点删除事件给所有待获取锁的客户端,但是只会有一个客户端获得锁。如果在集群规模比较大的情况下,会对Zookeeper服务器的性能产生比较大的影响。

基于临时顺序节点实现

为了解决惊群效应,我们可以采用基于临时顺序节点的方式来实现分布式锁。

实现方式:每个客户端都往/LOCK节点下注册一个临时有序节点,这个有序节点有一个可以代表客户端的编号,越早创建的节点,节点的顺序编号就越小,那么我们可以让顺序节点编号最小的节点设置为获得锁。如果自己的节点不是所有顺序节点中编号最小的,意味着还没有获得锁。这样,每个节点只需要监听比自己编号小的一个节点就行,当比自己小的节点删除后,客户端会收到删除事件,此时再次判断自己的顺序节点编号是不是所有节点中最小的,如果是,则获得锁,否则就不断重复这个过程,这样就不会产生惊群效应,因为每个客户端只需要监控一个节点。

 

比如现在有客户端A要对/LOCK节点加锁,Zookeeper会先在/LOCK下面创建一个顺序节点(假设编号为/LOCK-1),然后客户端A会查一下/LOCK这个锁节点下的所有顺序节点,A会做一个判断,我创建的那个顺序节点是不是最小的,如果是,则加锁成功。如果此时客户端B也想要加锁,B也得先在/LOCK下面创建一个顺序节点(假设编号为/LOCK-2),因为A还没有释放锁,所以此时/LOCK下面有两个顺序节点,然后B也要查一下/LOCK下面所有的顺序节点并判断自己创建的顺序节点是不是最小的,如果不是,则一直监听上一个比自己小的顺序节点的删除事件。如果A释放了锁,也就是A创建的顺序节点被删除了,Zookeeper就会通知监听这个顺序节点的监听器,也就是客户端B之前加的那个监听器,此时客户端B就可以成功获取锁了(因为它的顺序节点是最小的了)。

与基于临时节点实现方式比较的话,感觉就是多了个子顺序节点,这个顺序节点是有序的,谁的编号小,谁就可以获得锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值