zookeeper实现分布式锁服务
A distributed lock base on zookeeper.
zookeeper是hadoop下面的一个子项目, 用来协调跟hadoop相关的一些分布式的框架, 如hadoop, hive, pig等, 其实他们都是动物, 所以叫zookeeper(本人歪歪).
zookeeper其实是集群中每个节点都维护着一棵相同的树, 树的结构跟linux的目录结构的概念差不多, 以/为跟节点, 下边可以扩展任意的节点和叶子节点, 每个节点都可以写入数据. 基于zookeeper的分布式锁的实现, 其实是得益于zookeeper同步文件的强大性, 我们相信每时每刻我们访问zookeeper的树时, 相同节点返回的数据都是一致的. 这要靠zookeeper内部的一些算法来实现. 特别是leader的选举算法, 这里就不说了, 感兴趣的话可以去搜索一下看看.
我们知道了zookeeper集群的每个节点的数据都是一致的, 那么我们可以通过这些节点来作为锁的标志.
首先给锁设置一下API, 至少要包含, lock(锁住), unlock(解锁), isLocked(是否锁住)三个方法
然后我们可以创建一个工厂(LockFactory), 用来专门生产锁.
锁的创建过程如下描述:
前提:每个锁都需要一个路径来指定(如:/jiacheo/lock)
1.根据指定的路径, 查找zookeeper集群下的这个节点是否存在.(说明已经有锁了)
2. 如果存在, 根据查询者的一些特征数据(如ip地址/hostname), 当前的锁是不是查询者的
3. 如果不是查询者的锁, 则返回null, 说明创建锁失败
4. 如果是查询者的锁, 则把这个锁返回给查询者
5. 如果这个节点不存在, 说明当前没有锁, 那么创建一个临时节点, 并将查询者的特征信息写入这个节点的数据中, 然后返回这个锁.
根据以上5部, 一个分布式的锁就可以创建了.
创建的锁有三种状态:
1. 创建失败(null), 说明该锁被其他查询者使用了.’
2. 创建成功, 但当前没有锁住(unlocked), 可以使用
3. 创建成功, 但当前已经锁住(locked)了, 不能继续加锁.

如图, 如果我们getLock(“/jiacheo/lock1″,”192.168.0.100”), 想要获取/jiacheo/lock1这个锁的话, 我们先判断这个节点是否存在, 存在的话获取他的数据(data), 然后通过解析data, 我们可以知道这个节点是不是我们查询者创建的(通过ip地址写入节点数据中), 然后就可以返回一个锁了.
具体的java实现(implementation)代码如下:
1. Lock.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
package org.jiacheo.zkdl.lock;import java.net.InetAddress;import java.net.UnknownHostException;import org.apache.zookeeper.KeeperException;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.data.Stat;/** * 类名:<b>Lock</b> <br/> * <p> * 类描述: * </p> * 创建人:jiacheo <br/> * 创建时间:2011-1-27 上午01:30:25 <br/> * @version 2011-1-27 * */public class Lock { private String path; private ZooKeeper zooKeeper; public Lock(String path){ this.path = path; } /** * <p> * 方法描述: 上锁 lock it * </p> * 创建人:jiacheo <br/> * 创建时间:2011-1-27 上午01:30:50 <br/> * @throws Exception */ public synchronized void lock() throws Exception{ Stat stat = zooKeeper.exists(path, true); String data = InetAddress.getLocalHost().getHostAddress()+":lock"; zooKeeper.setData(path, data.getBytes(), stat.getVersion()); } /** * <p> * 方法描述:开锁 unlock it * </p> * 创建人:jiacheo <br/> * 创建时间:2011-1-27 上午01:31:20 <br/> * @throws Exception */ public synchronized void unLock() throws Exception{ Stat stat = zooKeeper.exists(path, true); String data = InetAddress.getLocalHost().getHostAddress()+":unlock"; zooKeeper.setData(path, data.getBytes(), stat.getVersion()); } /** * <p> * 方法描述:是否锁住了, isLocked? * </p> * 创建人:jiacheo <br/> * 创建时间:2011-1-27 上午01:31:43 <br/> * @return */ public synchronized boolean isLock(){ try { Stat stat = zooKeeper.exists(path, true); String data = InetAddress.getLocalHost().getHostAddress()+":lock"; String nodeData = new String(zooKeeper.getData(path, true, stat)); if(data.equals(nodeData)){// lock = true; return true; } } catch (UnknownHostException e) { // ignore it } catch (KeeperException e) { //TODO use log system and throw a new exception } catch (InterruptedException e) { // TODO use log system and throw a new exception } return false; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public void setZooKeeper(ZooKeeper zooKeeper) { this.zooKeeper = zooKeeper; } } |
2.LockFactory.java
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
package org.jiacheo.zkdl.lock;import java.io.IOException;import java.net.InetAddress;import java.util.Collections;import org.apache.zookeeper.CreateMode;import org.apache.zookeeper.WatchedEvent;import org.apache.zookeeper.Watcher;import org.apache.zookeeper.ZooKeeper;import org.apache.zookeeper.ZooDefs.Ids;import org.apache.zookeeper.ZooDefs.Perms;import org.apache.zookeeper.data.ACL;import org.apache.zookeeper.data.Stat;public class LockFactory { public static final ZooKeeper DEFAULT_ZOOKEEPER = getDefaultZookeeper(); //data格式: ip:stat 如: 10.232.35.70:lock 10.232.35.70:unlock public static synchronized Lock getLock(String path,String ip) throws Exception{ if(DEFAULT_ZOOKEEPER != null){ Stat stat = null; try{ stat = DEFAULT_ZOOKEEPER.exists(path, true); }catch (Exception e) { // TODO: use log system and throw new exception } if(stat!=null){ byte[] data = DEFAULT_ZOOKEEPER.getData(path, null, stat); String dataStr = new String(data); String[] ipv = dataStr.split(":"); if(ip.equals(ipv[0])){ Lock lock = new Lock(path); lock.setZooKeeper(DEFAULT_ZOOKEEPER); return lock; } //is not your lock, return null else{ return null; } } //no lock created yet, you can get it else{ createZnode(path); Lock lock = new Lock(path); lock.setZooKeeper(DEFAULT_ZOOKEEPER); return lock; } } return null; } private static ZooKeeper getDefaultZookeeper() { try { ZooKeeper zooKeeper = new ZooKeeper("10.232.35.72", 10*1000, new Watcher(){ public void process(WatchedEvent event) { //节点的事件处理. you can do something when the node's data change// System.out.println("event " + event.getType() + " has happened!"); } }); return zooKeeper; } catch (IOException e) { e.printStackTrace(); } return null; } private static void createZnode(String path) throws Exception{ if(DEFAULT_ZOOKEEPER!=null){ InetAddress address = InetAddress.getLocalHost(); String data = address.getHostAddress()+":unlock"; DEFAULT_ZOOKEEPER.create(path, data.getBytes(),Collections.singletonList(new ACL(Perms.ALL,Ids.ANYONE_ID_UNSAFE)) , CreateMode.EPHEMERAL); } } |
zookeeper实现分布式锁服务的更多相关文章
- Zookeeper实现分布式锁服务(Chubby)
在分布式系统中,如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰,来保证一致性,在这种情况下,便需要使用到分布式锁例如有N台服务器同时 ...
- [转载] zookeeper 分布式锁服务
转载自http://www.cnblogs.com/shanyou/archive/2012/09/22/2697818.html 分布式锁服务在大家的项目中或许用的不多,因为大家都把排他放在数据库那 ...
- zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- 基于Zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- Zookeeper系列四:Zookeeper实现分布式锁、Zookeeper实现配置中心
一.Zookeeper实现分布式锁 分布式锁主要用于在分布式环境中保证数据的一致性. 包括跨进程.跨机器.跨网络导致共享资源不一致的问题. 1. 分布式锁的实现思路 说明: 这种实现会有一个缺点,即当 ...
- 10分钟看懂!基于Zookeeper的分布式锁
实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...
- ZooKeeper示例 分布式锁
[转载请注明作者和原文链接, 如有谬误, 欢迎在评论中指正. ] 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程 ...
- 基于ZooKeeper实现——分布式锁与实现
引言 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提 ...
- java就业指南 zookeeper分布式系统 zookeeper实现分布式锁 有用
目前几乎很多大型网站及应用都是分布式部署的,分布式场景中的数据一致性问题一直是一个比较重要的话题.分布式的CAP理论告诉我们“任何一个 分布式系统都无法同时满足一致性(Consistency).可用性 ...
随机推荐
- python 列表、字典的方法
# 列表最后新增元素 li = [11, 22, 33] print(li) li.append(44) # 对原列表最后增加一个元素 print(li) 执行如下: [11, 22, 33][11, ...
- MySQL5.6新特性Index conditontion pushdow
index condition pushdown是MySQL5.6的新特性,主要是对MySQL索引使用的优化. Index condition push简称ICP,索引条件下推,将索引条件从serve ...
- Virtual Drive Manager V1.3.2(小巧实用的虚拟光驱)绿色版
软件名称: Virtual Drive Manager V1.3.2(小巧实用的虚拟光驱)汉化绿色修正版软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / Win2003 ...
- javascript动画效果之透明度(修改版)
在编写多块同时触发运动的时候,发现一个BUG, timer = setInterval(show, 30);本来show是一个自定义函数,当设为timer = setInterval(show(one ...
- B题 Before an Exam
Description Tomorrow Peter has a Biology exam. He does not like this subject much, but d days ago he ...
- AS3.0杂记——Dictionary、Object与Array
来源:http://blog.csdn.net/m_leonwang/article/details/8811829 Object.Array与Dictionary都是关联数组,就是用“键”来索引存储 ...
- vb6加载时提示出错,窗体log文件中错误信息为:控件 XX 的类 MSComctlLib.ListView 不是一个已加载的控件类。
解决办法:单击[工程] -- [部件] 添加此Microsoft Windows Common Controls-6.0 (SP6)部件,如果列表中没有,浏览到~\project\包\Support中 ...
- FreeMarker 小结
一.Sequence 的内置函数1.sequence?first 返回sequence 的第一个值.2.sequence?last 返回sequence 的最后一个值.3.sequence?rever ...
- .net 2.0 后台多线程
System.Threading.Thread thread1 = new System.Threading.Thread(delegate() { Web.BLL.banpaiconfig.Vide ...
- SmartImageView的使用
对于Android智能图像查看 SmartImageView是一个简易替换为Android标准的ImageView这还可以让图像从URL或用户的联系人地址簿加载.图片被缓存到内存和磁盘的超快速装载. ...