天天看点

Zookeeper 实现分布式锁思路解析及Curator实战

文章目录

    • 前言
    • 需要考虑的细节
        • 如果出现异常,没有删掉结点,进而这个锁永远无法释放,怎么办?
        • 如果在Finally之前服务器宕机了怎么办?
        • 如果事件监听机制会通知上轮取锁失败者,导致羊群效应怎么办?
    • 基于Curator实现Zookeeper实战

前言

Zookeeper实现分布式锁的核心在于

独占性

,即当有人创建过某结点,那么再次创建的时候,就不可创建,我们可根据是否能成功创建来实现

加锁

操作,而如何释放锁呢?走完流程删掉这个结点就可以了。

zk-客户端连接zk实现,如果重复创建会提示‘

Node already exists: /lock

’,在并发情况下,只有一个请求是可以创建成功的,其他的请求会通过

get -w

监听该节点

[zk: localhost:2181(CONNECTED) 20] create /lock
Created /lock
[zk: localhost:2181(CONNECTED) 21] create /lock
Node already exists: /lock
           

整体思路比较简单,但是要考虑很多细节。

需要考虑的细节

如果出现异常,没有删掉结点,进而这个锁永远无法释放,怎么办?

保证其释放了就行,例如在Java中可以使用

try catch

中的

finally

去保证其进行删除结点的操作

如果在Finally之前服务器宕机了怎么办?

这样Finally就失效了,此时我们想到了Zookeeper中的临时结点,让其自动释放

如果事件监听机制会通知上轮取锁失败者,导致羊群效应怎么办?

可以使用临时顺序节点,为所有的获取锁请求创建临时顺序结点,这样每个请求创建的临时顺序结点类似于lock0000001、lock0000002…这样的形式,每次编号最小的获取结点,且编号次小的会对编号最小的顺序结点进行监听,也就是2监听1,3监听2这种… ,2监听到1释放了,2就会拿锁,这样就避免了羊群效应。

基于Curator实现Zookeeper实战

Curator是Zookeeper客户端工具,也就是说我们可以在自己的系统中集成Curator,并借助它对Zookeeper进行操作。

引入Curator依赖

<dependency>
     <groupId>org.apache.curator</groupId>
     <artifactId>curator-recipes</artifactId>
     <version>4.3.0</version>
</dependency>
           

继续阅读