ZooKeeper如何完成分布式锁?
* 面试答案为LZ所写,如需转载请注明出处,谢谢。
1.最基本的思路:
将<local_ip>:<task_id>存在某个路径节点里。
刚开始并没有这个节点,当有executor执行操作时,都会询问这个节点。
如果不存在,则创建这个临时节点,并将<local_ip>:<task_id>写进去。
如果存在,则比对<local_ip>:<task_id>是否与这个临时节点中的数据<local_ip>:<task_id>一致,若一致,则允许运行,若不一致,则阻塞。
总结一下,如何识别唯一的一个executor? 通过<local_ip>:<task_id>来识别。那如何进行每个executor之间的互斥?那就是通过写入临时节点上的数据的方式来允许执行。
也就是说,某个指定临时节点上的数据<local_ip>:<task_id>是允许哪个executor运行的唯一标志。
2.方法
核心的三个方法为connect、lock、unlock方法。
1)connect方法
思路:
STEP1:进行ZK连接,如连接不上则重试
STEP2:检查是否存在该临时节点,如不存在则创建,以<local_ip>:<task_id>为数据内容。
public void connect() {
try {
// STEP1:进行ZK连接,如连接不上则重试
zk = new ZooKeeper("node1:2181,node3:2181", 3000, new Watcher() {
// 监控zk状态
@Override
public void process(WatchedEvent event) {
// System.out.println("event:" + event.getType());
}
});
// 连接重试
while (zk.getState() != ZooKeeper.States.CONNECTED) {
Thread.sleep(1000);
}
// STEP2: STEP2:检查是否存在该临时节点,如不存在则创建,以<local_ip>:<task_id>为数据内容。
// <ip>:<taskID> 格式作为识别格式
InetAddress ip = InetAddress.getLocalHost();
lockData = ip.getHostAddress() + ":" + context.getThisTaskId();
// 如果没有节点
if (zk.exists(zk_path, false) == null) {
zk.create(zk_path, lockData.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
}
} catch (Exception e) {
this.unlock();
e.printStackTrace();
}
}
2).lock方法
思路:
STEP1:获得节点数据,如果节点不存在,则使用connect()方法重新连接创建节点。
STEP2:比对节点数据与本地的<local_ip>:<task_id>,如果一致,则返回方法,继续执行业务内容。如果不一致,则阻塞,每隔一段时间检查一次。
public void lock() {
// 互斥逻辑
String nodeData;
try {
nodeData = new String(zk.getData(zk_path, false, null));
while (!lockData.equals(nodeData) || nodeData==null) {
// 若节点不存在,重新连接
if(nodeData == null){
connect();
}else{
Thread.sleep(10);
}
}
} catch (Exception e) {
}
}
3).unlock方法
思路:
因为这个临时节点是依赖连接存在的,所以unlock方法直接断开连接就可以释放临时节点。
public void unlock() {
try {
zk.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ZooKeeper如何完成分布式锁?的更多相关文章
- 如何用Zookeeper来实现分布式锁?
什么是Zookeeper临时顺序节点? 例如 : / 动物 植物 猫 仓鼠 荷花 松树 Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Zonde.# Znode分为四种类型 ...
- 基于zookeeper实现的分布式锁
基于zookeeper实现的分布式锁 2011-01-27 • 技术 • 7 条评论 • jiacheo •14,941 阅读 A distributed lock base on zookeeper ...
- java使用zookeeper实现的分布式锁示例
java使用zookeeper实现的分布式锁示例 作者: 字体:[增加 减小] 类型:转载 时间:2014-05-07我要评论 这篇文章主要介绍了java使用zookeeper实现的分布式锁示例,需要 ...
- ZooKeeper 笔记(6) 分布式锁
目前分布式锁,比较成熟.主流的方案有基于redis及基于zookeeper的二种方案. 大体来讲,基于redis的分布式锁核心指令为SETNX,即如果目标key存在,写入缓存失败返回0,反之如果目标k ...
- 基于Zookeeper实现多进程分布式锁
一.zookeeper简介及基本操作 Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化.当对目录节点监控状态打开时,一旦目录节点的状态发生变化,Watc ...
- 利用ZooKeeper简单实现分布式锁
1.分布式锁的由来: 在程序开发过程中不得不考虑的就是并发问题.在java中对于同一个jvm而言,jdk已经提供了lock和同步等.但是在分布式情况下,往往存在多个进程对一些资源产生竞争关系,而这些进 ...
- 基于zookeeper简单实现分布式锁
https://blog.csdn.net/desilting/article/details/41280869 这里利用zookeeper的EPHEMERAL_SEQUENTIAL类型节点及watc ...
- 基于zookeeper实现高性能分布式锁
实现原理:利用zookeeper的持久性节点和Watcher机制 具体步骤: 1.创建持久性节点 zkLock 2.在此父节点下创建子节点列表,name按顺序定义 3.Java程序获取该节点下的所有顺 ...
- zookeeper实现的分布式锁
在分布式系统中,多个jvm对共享资源进行操作时候,要加上锁,这就是分布式锁 利用zookeeper的临时节点的特性,可以实现分布式锁 public class ZookeeperDistrbuteLo ...
- Zookeeper怎么实现分布式锁?
对访问资源 R1 的过程加锁,在操作 O1 结束对资源 R1 访问前,其他操作不允许访问资源 R1.以上算是对独占锁的简单定义了,那么这段定义在 Zookeeper 的"类 Unix/Lin ...
随机推荐
- Qt QLineEdit 漂亮的搜索框 && 密码模式 && 格式化输入 && 提示文字 && 选择内容并移动 && 清除全部输入
先上一个漂亮的搜索框效果图, 输入搜索文本效果, 点击搜索图标效果: //实现代码 void MainWindow::iniLineEdit() { ui->lineEdit->setPl ...
- phpstorm----------phpstorm设置自动更新的ssh信息如何修改--后续增加如何设置自动更新
1.如何设置phpstorm将本地代码时时同步到远程服务器 注意下面一定要打勾 点击下一步,然后还有一个页面,然后不用做任何操作,直接点击完成.中途有个页面是输入远程服务器ip账号密码链接方式的,那个 ...
- mysql中utf8和utf8mb4区别
一.什么是utf8mb4 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode.好在utf8mb4是utf8的超集,除 ...
- luogu P3197 [HNOI2008]越狱
构造长度为n的串,给定m种颜色,求使得相邻两位的颜色相同的方案数 显然可以看出长度为n的串染m种颜色的总方案数为$m^{n}$ 然后来考虑相邻两位颜色不同的方案 对于第一位,有m种选择 对于剩余的n- ...
- 【论文速读】Fangfang Wang_CVPR2018_Geometry-Aware Scene Text Detection With Instance Transformation Network
Han Hu--[ICCV2017]WordSup_Exploiting Word Annotations for Character based Text Detection 作者和代码 caffe ...
- GIL
GIL(Global Interpreter Look):全局解释器锁,为了避免线程竞争资源造成数据错乱. 其实每个py程序都必须有解释器参加,解释器就是一堆代码,就等于多线程要竞争同一个解释器的代码 ...
- ASP.NET页面之间传值的方式之Server.Transfer(个人整理)
Server.Transfer 这个方法相比以前介绍的方法稍微复杂一点,但在页面间值传递中却是特别有用的,使用该方法你可以在另一个页面以对象属性的方式来存取显露的值,当然了,使用这种方法,你需要额外写 ...
- redis的 rdb 和 aof 持久化的区别
aof,rdb是两种 redis持久化的机制.用于crash后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个d ...
- poj 2115 Matrix
题意: 给出一个矩阵,有两种操作: 1.翻转给定的子矩阵: 2.查询a[i][j]的值. 思路: 树状数组是从小到大更新的. 这个题用二维树状数组可以解决,假设是一维树状数组, 0 0 0 0 0 0 ...
- python locust 性能测试:HOOKS<钩子方法>
为locust中不同类型的事件,提供的钩子方法: from locust import TaskSet, task, events, Locust from locust.clients import ...