ZK实现分布式锁原理

目录

一、引入问题

二、了解ZK

三、ZK实现分布式锁过程

四、图解ZK实现分布式锁过程


文字有点多,也可以直接进入图解过程

一、引入问题

单进程jvm下,可以用java内置锁和显示锁来确保线程安全。但是在多jvm下时,如何保证线程安全呢,java层级已经解决不了这个问题。也就是说不同的jvm如何保证资源安全性?引出ZK解决分布式带来的资源同步问题

二、了解ZK

理解节点,为实现分布式锁铺垫。

ZK有四种节点

1、持久节点

扫描二维码关注公众号,回复: 11880782 查看本文章

默认的节点类型。创建节点的客户端与zookeeper断开连接后,该节点依旧存在。

2、持久节点顺序节点

在创建节点时,zookeeper根据创建的时间顺序给该节点名称进行编号

3、临时节点

和持久节点相反,当创建节点的客户端与zookeeper断开连接后,临时节点会被删除

4、临时顺序节点

在创建节点时,zookeeper根据创建的时间顺序给该节点名称进行编号排序(排序的节点形成一个类似队列)。当创建节点的客户端与zookeeper断开连接后,临时节点会被删除(解锁)

三、ZK实现分布式锁过程

这里我以三个不同的客户端client1、client2、client3来演示ZK实现分布式锁的过程。

1、首先,在ZK创建一个持久节点ParentLock。当第一个客户端想要获得锁时,需要在ParentLock这个节点下面创建一个临时顺序的节点(临时节点1),client1查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点(临时节点1)是不是顺序最靠前的一个。如果是则成功获得锁。执行同步代码块。

2、这个时候,如果再有一个客户端client2(可以理解成不同的进程)前来获取锁,则ParentLock下再创建一个临时顺序节点(临时节点2)。client2查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点(临时节点2)是不是顺序最靠前的一个,发现不是最小,于是,client2向前排序仅比它靠前的节点注册Watcher,用来监听--临时节点1是否存在。这意味着client2抢锁失败。

3、这个时候,又有一个客户端client3前来获取锁,则ParentLock下再创建一个临时顺序节点(临时节点3)。client3查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点(临时节点3)是不是顺序最靠前的一个,发现不是最小,于是,client3向前排序仅比它靠前的节点注册Watcher,用来监听--临时节点2是否存在。这意味着client3抢锁失败。

4、客户端client1执行完同步代码块,断开与zookeeper连接,对应的临时节点1也会被删除,解锁成功。此时client2监听到临时节点1不存在,于是拿到锁。执行同步代码块。

5、客户端client2执行完同步代码块,断开与zookeeper连接,对应的临时节点2也会被删除,解锁成功。此时client3监听到临时节点2不存在,于是拿到锁。执行同步代码块。

6、客户端client3执行完同步代码块,断开与zookeeper连接,对应的临时节点3也会被删除,解锁成功

四、图解ZK实现分布式锁过程

1、client1拿锁解释过程,不涉及分布式锁

2、这里我以三个不同的客户端client1、client2、client3来演示ZK实现分布式锁的过程。

1.client1拿锁,创建临时节点1并排序,临时节点1在第一位,成功拿锁==执行同步代码块

2.client2拿锁,创建临时节点2并排序,临时节点2不在第一位,创建监听器监听前面一个临时节点1,拿锁失败==监听中

3.client3拿锁,创建临时节点3并排序,临时节点3不在第一位,创建监听器监听前面一个临时节点2,拿锁失败==监听中。

此时client2也在监听着临时节点1

4.client1同步代码执行完毕断开与zookeeper连接,删除临时节点1,相当于释放锁。

client2一直监听着临时节点1,发现其不存在,拿锁成功==执行同步代码块

client3继续监听

5.client2同步代码执行完毕断开与zookeeper连接,删除临时节点2,相当于释放锁。

client3一直监听着临时节点2,发现其不存在,拿锁成功==执行同步代码块

6.client3同步代码执行完毕断开与zookeeper连接,删除临时节点3,相当于释放锁。

猜你喜欢

转载自blog.csdn.net/qq_41055045/article/details/103831625