Curator框架实现ZooKeeper分布式锁
排他锁(X)
这里主要讲讲分布式锁中的排他锁。排他锁(Exclusive Locks,简称X锁),又称为写锁或独占锁,是一种基本的锁类型。如果事务T1对数据对象O1加上了排他锁,那么在整个加锁期间,只允许T1对O1进行数据的读取和更新操作,其它任何事务都不能对O1进行任何类型的操作,直道T1释放了排他锁。
定义锁
在ZooKeeper中,可以通过在ZooKeeper中创建一个数据节点来表示一个锁。比如,/exclusive_lock/lock节点(znode)就可以表示为一个锁。

获取锁
在需要获取排他锁时,所有的客户端都会试图通过create()接口,在/exclusive_lock节点下创建临时的子节点/exclusive_lock/lock,但ZooKeeper的强一致性最终只会保证仅有一个客户单能创建成功,那么就认为该客户端获取了锁。同时,所有没有获取锁的客户端事务只能处于等待状态,这些处于等待状态的客户端事先可以在/exclusive_lock节点上注册一个子节点变更的Watcher监听,以便实时监听到子节点的变更情况。
释放锁
在“定义锁”部分,我们已经提到/exclusive_lock/lock是一个临时节点,因此在以下两种情况下可能释放锁。
- 当前获取锁的客户端发生宕机,那么ZooKeeper服务器上保存的临时性节点就会被删除;
- 正常执行完业务逻辑后,由客户端主动来将自己创建的临时节点删除。
无论什么情况下,临时节点/exclusive_lock/lock被移除,ZooKeeper都会通知在/exclusive_lock注册了子节点变更Watcher监听的客户端。这些客户端在接收到通知以后就会再次发起获取锁的操作,即重复“获取锁”过程。排他锁流程如下:

下面的代码(java)演示了使用Curator框架来实现ZooKeeper分布式锁
import java.util.concurrent.TimeUnit;
import lombok.Cleanup;
import lombok.SneakyThrows;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat; public class ZkLock { @SneakyThrows
public static void main(String[] args) { final String connectString = "localhost:2181,localhost:2182,localhost:2183"; // 重试策略,初始化每次重试之间需要等待的时间,基准等待时间为1秒。
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); // 使用默认的会话时间(60秒)和连接超时时间(15秒)来创建 Zookeeper 客户端
@Cleanup CuratorFramework client = CuratorFrameworkFactory.builder().
connectString(connectString).
connectionTimeoutMs(15 * 1000).
sessionTimeoutMs(60 * 100).
retryPolicy(retryPolicy).
build(); // 启动客户端
client.start(); final String lockNode = "/lock_node";
InterProcessMutex lock = new InterProcessMutex(client, lockNode);
try {
// 1. Acquire the mutex - blocking until it's available.
lock.acquire(); // OR // 2. Acquire the mutex - blocks until it's available or the given time expires.
if (lock.acquire(60, TimeUnit.MINUTES)) {
Stat stat = client.checkExists().forPath(lockNode);
if (null != stat){
// Dot the transaction
}
}
} finally {
if (lock.isAcquiredInThisProcess()) {
lock.release();
}
}
} }
maven引用
<!--curator这个开源项目提供zookeeper分布式锁实现-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
Curator框架实现ZooKeeper分布式锁的更多相关文章
- Curator实现zookeeper分布式锁的基本原理
一.写在前面 之前写过一篇文章(<拜托,面试请不要再问我Redis分布式锁的实现原理>),给大家说了一下Redisson这个开源框架是如何实现Redis分布式锁原理的,这篇文章再给大家聊一 ...
- 女朋友也能看懂的Zookeeper分布式锁原理
前言 关于分布式锁,在互联网行业的使用场景还是比较多的,比如电商的库存扣减,秒杀活动,集群定时任务执行等需要进程互斥的场景.而实现分布式锁的手段也很多,大家比较常见的就是redis跟zookeep ...
- ZooKeeper分布式锁的实现原理
七张图彻底讲清楚ZooKeeper分布式锁的实现原理[石杉的架构笔记] 文章转载自:https://juejin.im/post/5c01532ef265da61362232ed#comment(写的 ...
- ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁
前言 在了解了加锁和锁重入之后,最需要了解的还是在分布式场景下或者多线程并发加锁是如何处理的? 并发加锁 先来看结果,在多线程对 /locks/lock_01 加锁时,是在后面又创建了新的临时节点. ...
- Zookeeper分布式锁实现Curator十一问
前面我们剖析了Redisson的源码,主要分析了Redisson实现Redis分布式锁的15问,理清了Redisson是如何实现的分布式锁和一些其它的特性.这篇文章就来接着剖析Zookeeper分布式 ...
- Curator Zookeeper分布式锁
Curator Zookeeper分布式锁 pom.xml中添加如下配置 <!-- https://mvnrepository.com/artifact/org.apache.curator/c ...
- ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放
ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放 前言 加锁逻辑已经介绍完毕,那当一个线程重复加锁是如何处理的呢? 锁重入 在上一小节中,可以看到加锁的过程,再回头看 ...
- ZooKeeper 分布式锁 Curator 源码 04:分布式信号量和互斥锁
前言 分布式信号量,之前在 Redisson 中也介绍过,Redisson 的信号量是将计数维护在 Redis 中的,那现在来看一下 Curator 是如何基于 ZooKeeper 实现信号量的. 使 ...
- Zookeeper 分布式锁 (图解+秒懂+史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
随机推荐
- 05-Vue组件
定义Vue组件 什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可: 组件化和模块化的不同: ...
- pyqt5--TableWidGet
使用pyqt5展示excel的数据到桌面,并获取选中的数据内容 from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtGui import Q ...
- Nikto 扫描工具
一.渗透步骤 信息收集 (被动的信息收集,主动的信息收集) 扫描探测 制定攻击方向 渗透 留后门 课堂分享: 书籍: <使用kali Linux进行web渗透测试>--书中部分工具已经无法 ...
- httprunner学习19-重复执行用例
前言 使用httprunner做接口测试过程中,在工作中会遇到这种场景,发现某个接口不稳定,想重复运行100次用例,甚至1000次,看成功率. yml脚本 - config: name: httpbi ...
- G6 学习资料
G6 学习资料 网址 G6 1.x API 文档 http://antvis.github.io/g6/doc/index.html 官方demo列表 https://github.com/antvi ...
- Mac下用命令行获取苹果手机的UDID
在终端输入命令行:system_profiler SPUSBDataType | grep "Serial Number:.*" | sed s#".*Serial Nu ...
- Maven 学习(一)-Maven 使用入门
http://www.cnblogs.com/xdp-gacl/p/3498271.html http://www.cnblogs.com/xdp-gacl/p/4240930.html 一.Mave ...
- Collections.synchronizedList使用
1.SynchronizedList类具体代码: static class SynchronizedList<E> extends SynchronizedCollection<E& ...
- Arduino在串口监视器上输出字母表
程序会在Arduino IDE的串口监视器上输出一个字母表. 不需要额外电路,但是板子必须通过串口线或USB线连接到电脑. 代码 程序在setup()函数中建立串口连接,然后逐行输出a~z的字母I表, ...
- virtual abstract override
virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义. 它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能 ...