zookeeper-分布式锁的代码实现-【每日五分钟搞定大数据】
本文涉及到几个zookeeper简单的知识点,永久节点、有序节点、watch机制。比较基础,熟悉的就别看了跳过这篇吧
- 每个线程在/locks节点下创建一个临时有序节点test_lock_0000000040
- 获得/locks节点下所有子节点A、B、C,排序获得最小值
- 若当前节点B为最小值则获得锁,执行业务逻辑
- 若当前节点B不是最小值则watch比自己小1的节点A,节点A存在则await,否则获得锁
总结:临时有序节点排序后watch比自己小1的节点。
下面看代码
1.线程初始化
创建一个名字为lockName的永久节点(只有永久节点才可以创建子节点)
DistributedLock(String url, String lockName) {
this.lockName = lockName;
try {
zkConn = new ZooKeeper(url, sessionTimeout, this);
if (zkConn.exists(ROOT_LOCK, false) == null)
zkConn.create(ROOT_LOCK, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch (IOException | InterruptedException | KeeperException e) {
e.printStackTrace();
}
}
复习一下:zookeeper的节点有以下几种类型:永久,永久有序,临时,临时有序
public enum CreateMode {
PERSISTENT(0, false, false),
PERSISTENT_SEQUENTIAL(2, false, true),
EPHEMERAL(1, true, false),
EPHEMERAL_SEQUENTIAL(3, true, true);
2.线程尝试获得锁tryLock
创建临时有序节点,会在你的lockName后面加上一串编号,例如/locks/test_lock_0000000035
CURRENT_LOCK = zkConn.create(ROOT_LOCK + "/" + lockName + splitStr, new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
获取当前lockName下的所有子临时节点
List<String> subNodes = zkConn.getChildren(ROOT_LOCK, false);
把名字都取出来放进list排个序
List<String> lockObjects = new ArrayList<>();
for (String node : subNodes) {
String _node = node.split(splitStr)[0];
if (_node.equals(lockName)) lockObjects.add(node);
}
若当前节点为最小节点,则直接获取锁成功
if (CURRENT_LOCK.equals(ROOT_LOCK + "/" + lockObjects.get(0))) {
return true;
}
若不是最小节点,开始等待,见下一步。
3.开始等待锁
获得当前线程需要等待的节点名
- 获得当前节点的节点名即test_lock_0000000035
- 获得当前几点在所有排队等锁的线程中的排序
- 根据排序-1,获得排在自己前面的线程的节点名
String prevNode = CURRENT_LOCK.substring(CURRENT_LOCK.lastIndexOf("/") + 1);
int prevNodePosition = Collections.binarySearch(lockObjects, prevNode);
WAIT_LOCK = lockObjects.get(prevNodePosition - 1);
给exists加上watcher,监控当前线程等待的节点waitLock是否还存在
若存在即stat不为null,当前线程先开始await
同时watch线程也启动了开始监控exists操作
若是exists状态有变化了(即waitLock不存在了)触发watch线程的countDown操作。
countDown操作使当前线程结束waiting,获得锁,开始继续往后执行
private boolean waitForLock(String waitLock, long waitTime) throws KeeperException, InterruptedException {
Stat stat = zkConn.exists(ROOT_LOCK + "/" + waitLock, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if (countDownLatch != null) {
countDownLatch.countDown();
}
}
});
if (stat != null) {
System.out.println(Thread.currentThread().getName() + " is waiting for " + ROOT_LOCK + "/" + waitLock);
this.countDownLatch = new CountDownLatch(1);
this.countDownLatch.await(waitTime, TimeUnit.MILLISECONDS);
this.countDownLatch = null;
System.out.println(Thread.currentThread().getName() + " get the lock ");
}
return true;
}
完整的代码可以在我的公众号后台回复9获得,感谢阅读。
zookeeper-分布式锁的代码实现-【每日五分钟搞定大数据】的更多相关文章
- zookeeper核心-zab协议-《每日五分钟搞定大数据》
上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...
- zookeeper-架构设计与角色分工-《每日五分钟搞定大数据》
本篇文章阅读时间5分钟左右 点击看<每日五分钟搞定大数据>完整思维导图 zookeeper作为一个分布式协调系统,很多组件都会依赖它,那么此时它的可用性就非常重要了,那么保证可用性的同 ...
- HDFS-异常大全-《每日五分钟搞定大数据》
点击看<每日五分钟搞定大数据>完整思维导图以及所有文章目录 问题1:Decomminssioning退役datanode(即删除节点) 1.配置exclude: <name>d ...
- zookeeper-操作与应用场景-《每日五分钟搞定大数据》
Zookeeper作为一个分布式协调系统提供了一项基本服务:分布式锁服务,分布式锁是分布式协调技术实现的核心内容.像配置管理.任务分发.组服务.分布式消息队列.分布式通知/协调等,这些应用实际上都是基 ...
- zookeeper-如何修改源码-《每日五分钟搞定大数据》
本篇文章仅仅是起一个抛砖迎玉的作用,举一个如何修改源码的例子.文章的灵感来自 ZOOKEEPER-2784. 提一个问题先 之前的文章讲过zxid的设计,我们先复习下: zxid有64位,分成两部分: ...
- zookeeper-监控与优化-《每日五分钟搞定大数据》
本文的命令和配置都是基于zookeeper-3.4.6版本.优化很多时候都是基于监控的,所以把这两个内容写在了一起,慢慢消化. 监控 简单地说,监控无非就是获取服务的一些指标,再根据实际业务情况给这些 ...
- redis- info调优入门-《每日五分钟搞定大数据》
本文根据redis的info命令查看redis的内存使用情况以及state状态,来观察redis的运行情况以及需要作出的相应优化. info 1.memory used_memory:13409011 ...
- 五分钟搞定Go.js
五分钟搞定Go.js 1.基于html5~因为Go.js是一个依赖于HTML5特性的JavaScript库,所以需要确保您的页面声明它是一个HTML5文档,当然需要加载库 <!DOCTYPE ...
- 五分钟搞定Linux容器
[TechTarget中国原创] Linux容器针对特定工作负载提供了全新的灵活性与可能性.存在很多解决方案,但是没有一个解决方案能够像systemd容器那样进行快速部署.给我五分钟,本文将介绍如何使 ...
随机推荐
- (python)排序算法
一.冒泡排序 1.冒泡排序实现思路 需要两层循环,外层循环控制总共循环几次,内层循环控制交换的次数(注意索引超界的问题). 外层第一次循环,内层第一次循环,将第一个元素(y)与第二个元素(y+1)进行 ...
- Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库
1.第一步,在本地数据库中建一个与服务器同名的数据库 2.第二步,右键源数据库,任务>导出数据,弹出导入导出提示框,点下一步继续 3.远程数据库操作,确认服务器名称(服务器地址).身份验证(输入 ...
- 在Lua中提示UnityEngine.dll的方法
我的环境 安装最新的 EmmyLua-1.2.1及以上版本 IDEA 2017.1.2 及以上版本 关于EmmlyLua的介绍可查看我之前的文章:Lua代码提示和方法跳转 说明:本文方法摘自 Emmy ...
- JavaScript实现元素拖动性能优化
前言:前几天没事干写了个小网站,打算用原生的javascript实现元素的拖动,但是事情并没有想象的那么顺利,首先是实现了拖动的元素卡的不能再卡,简直不能够,上图~~ 看见没?这就是效果,简直让人欲哭 ...
- JaveScript 中使用 XSLT转换XML文档
我们经常将数据存储在XML 中,在展示的时候需要转换为其它的形式,这里介绍使用XSLT 对XML数据进行转换. 要学习XSLT对XML的转换,需要先了解三个文件. 第一个是存储数据的XML文件:emp ...
- burp抓取手机模拟器流量
这里安装的是夜神模拟器,网络模式设置为桥接: 然后从burp suite 导出证书,存为.cer格式.将其导入手机模拟器(我用百度网盘导入的,自带的文件导入,不太会用,找不到放哪了) 然后给手机模拟器 ...
- February 24th, 2018 Week 8th Saturday
Those are my principles, and if you don't like them... well, I have others. 那是我的原则,要是你不喜欢......那我还有其 ...
- IntelliJ IDEA 创建Spring+SpringMVC+hibernate+maven项目
第一步: 新建maven管理的web项目, 具体步骤参考:http://www.cnblogs.com/gczmn/p/8693734.html 第二步: 创建项目结构, 完整项目结构如下: 第三步: ...
- Quartz简答介绍
引言 Quartz是开源任务调度框架中的翘楚,提供了强大的任务调度机制.Quartz允许开发人员灵活地定义触发器的调度时间表,并可对触发器和任务进行关联映射.此外,Quartz提供了调度运行环境的持久 ...
- openPose-注
静态编译出错:MD能通过 \ https://blog.csdn.net/Silver_sail/article/details/40540887 E:\project\BodyPoseEstimat ...