分布式之Zookeeper一(分布式锁与Zookeeper集群)
说到分布式开发,不得不说的就是zookeeper了;zookeeper官网说到Apache ZooKeeper致力于开发和维护可实现高度可靠的分布式协调的开源服务器。那么zk作为一个协调者的存在,是分布式比不可少的一部分。废话不多说,直接上干货
Zookeeper(https://zookeeper.apache.org/)的安装包可以直接在官网上获取,https://zookeeper.apache.org/doc/current/zookeeperStarted.html这里有Zookeeper的一些常用的简单命令,我们可以尝试着去试试它。
下面来说分布式锁,它用到的场景;比如:我们常说的惊群效应、Zookeeper集群争先读取缓存等。这里可能有人提到用redis实现的分布式锁,其实对比redis和Zookeeper的官网叙述,我们就能清晰的发现:Zookeeper比Redis更适合去做分布式锁。Zookeeper的担保第一条就是它的顺序性和一致性,其次是它的原子性。大家也可以详细的去了解一下。再分清楚这些之后,我们可以试着思考下Zookeeper它是怎么去实现的分布式锁?根据什么去实现的?
可以想到如何获取到Zookeeper的每个节点以及子节点变化,Zookeeper的Watch机制充分的实现了这一点。通过Watch机制可以清晰的监听到Zookeeper的每个节点的变化。自然而然的这里也要用到Zookeeper的第三方客户端。Zookeeper的第三方客户端有两个;一个是zkclient、一个是curator。在curator中它自己已经实现了分布式锁,感兴趣的可以去看看它的实现源码。
在第三方客户端连接到Zookeeper之后,就可以开始实现分布式锁了。锁的排他性、堵塞性、可重入性。排他性zk默认就实现了,zk的节点必须是唯一的。分布式锁采用Zookeeper的临时顺序节点来实现,首先获取锁,创建一个Zookeeper的临时顺序节点;然后需要一个栅栏(CountDownLatch),确保所有人都拿到自己的编号,即在同一起跑线上。然后开始抢锁,给一个发令枪(CountDown)。然后抢到锁的就去执行自己的业务,watch再次监听节点数据变化,然后请求线程去进行阻塞等待,接下来再删除节点,释放锁。
public boolean tryLock() {
if(currentPath.get() == null || !client.exists(currentPath.get())) {
String node = client.createEphemeralSequential(LockPath+"/", "locked");
currentPath.set(node);
}
List<String> children =client.getChildren(LockPath);
// 排序list
Collections.sort(children);
// 判断当前节点是否是最小的
if(currentPath.get().equals(LockPath+"/"+children.get(0))) {
return true;
}else {
int curIndex = children.indexOf(currentPath.get().substring(LockPath.length() + 1));
String bnode = LockPath+"/"+children.get(curIndex -1);
beforePath.set(bnode);
}
return false;
}
public void lock() {
if(! tryLock()) {
// 阻塞等待锁的释放
waitForLock();
// 重新抢锁
lock();
}
}
private void waitForLock() {
CountDownLatch cdl = new CountDownLatch(1);
// 用zkwatcher事件来通知
IZkDataListener listener = new IZkDataListener() {
public void handleDataDeleted(String dataPath) throws Exception {
System.out.println("================zk节点被删除================");
cdl.countDown();
}
public void handleDataChange(String dataPath, Object data) throws Exception {
}
};
// watcher /zk 数据变化
client.subscribeDataChanges(beforePath.get(), listener);
// 请求线程去进行阻塞等待
if(client.exists(beforePath.get())) {
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 取消注册事件
client.unsubscribeDataChanges(beforePath.get(), listener);
}
至此一个分布式锁就实现了。
接下来说Zookeeper的伪集群。搭建的时候需要注意的情况:
1、DataDir的位置。
2、Zookeeper的端口号
3、

4、myid文件,myid文件是创建在DataDir目录下的,myid文件就是给一个id数,id数需与server.1 ... 后边的编号一致。
然后分别启动三台服务器,注意看服务器输出的日志消息。不出意外的话Zookeeper的集群就可以搭建成功了!
分布式之Zookeeper一(分布式锁与Zookeeper集群)的更多相关文章
- zookeeper的单实例和伪集群部署
原文链接: http://gudaoyufu.com/?p=1395 zookeeper工作方式 ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现 ...
- Zookeeper笔记之使用zk实现集群选主
一.需求 在主从结构的集群中,我们假设硬件机器是很脆弱的,随时可能会宕机,当master挂掉之后需要从slave中选出一个节点作为新的master,使用zookeeper可以很简单的实现集群选主功能. ...
- ZooKeeper实践:(2)集群管理
前言: 随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机 ...
- ZooKeeper实践:(1)集群管理
前言: 随着业务的扩大,用户的增多,访问量的增加,单机模式已经不能支撑,从而出现了从单机模式->垂直应用模式->集群模式,集群模式诞生了,伴随着一堆问题也油然而生,Master怎么选举,机 ...
- zookeeper在windows下的伪集群模式
参考:zookeeper在windows下的伪集群模式 踩到的坑: 注意windows下路径需要使用\ dataDir=D:\Program Files\Java\zookeeper-3.4.10-c ...
- docker swarm英文文档学习-11-上锁你的集群来保护你的加密密钥
Lock your swarm to protect its encryption key上锁你的集群来保护你的加密密钥 在Docker 1.13及更高版本中,默认情况下,群管理器使用的Raft日志在 ...
- Zookeeper节点增删改查与集群搭建(笔记)
1.上传文件目录说明 上传的文件一般放在 /home/下 安装文件一般在 /usr/local/下 2. 安装zookeeper 2.1将zookeeper-3.4.11.tar.gz拷贝到/home ...
- (1)Zookeeper在linux环境中搭建集群
1.简介 ZooKeeper是Apache软件基金会的一个软件项目,它为大型分布式计算提供开源的分布式配置服务.同步服务和命名注册.ZooKeeper的架构通过冗余服务实现高可用性.Zookeeper ...
- 分布式Hbase-0.98.4在Hadoop-2.2.0集群上的部署
fesh个人实践,欢迎经验交流!本文Blog地址:http://www.cnblogs.com/fesh/p/3898991.html Hbase 是Apache Hadoop的数据库,能够对大数据提 ...
- Zookeeper 2、Zookeeper的安装和配置(集群模式)
1.下载与解压 Zookeeper下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载完成以后解压到一个特定目录 同步时间所有节点的时间,并关 ...
随机推荐
- Python list、tuple、dict区别
Dictionary 是 Python 的内置数据类型之一, 它定义了键和值之间一对一的关系. 每一个元素都是一个 key-value 对, 整个元素集合用大括号括起来 您可以通过 key 来引用其值 ...
- 【POJ - 3641】Pseudoprime numbers (快速幂)
Pseudoprime numbers Descriptions 费马定理指出,对于任意的素数 p 和任意的整数 a > 1,满足 ap = a (mod p) .也就是说,a的 p 次幂除以 ...
- APP安全_Android反编译
反编译 Android的反编译工具:apktool,JEB等. Apk 文件的结构,如下: META-INF:签名文件 res:资源文件,里面的 xml 格式文件在编译过程中由文本格式转化为二进制的 ...
- git pull因为主线分支问题解决
方法1:如果你想保留刚才本地修改的代码,并把git服务器上的代码pull到本地(本地刚才修改的代码将会被暂时封存起来) git stashgit pull origin mastergit stash ...
- My life
突然想到的好笑的: 1. 世界上一共有10种人,一种是男人,另一种是女人 2. 吐槽一个网站的域名: 你这网站域名取得,跟色情网站似的 明知这是一场意外,你要不要来,明知这是一场重伤害,你会不会来: ...
- POJ1703Find them, Catch them 【种类并查集】
题目链接:http://poj.org/problem?id=1703 题目大意:给n个人,m次询问.A代表询问a, b之间的关系,D代表给出a, b属于不同的帮派. 我的想法: 太菜了,上课的时候没 ...
- Minimum Number of Arrows to Burst Balloons
There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided ...
- Log4j2日志配置详解(2)
Log4j2日志配置系列之2 1.Configuration 在应用程序代码中插入日志请求需要相当多的计划和工作.观察显示,大约4%的代码用于日志记录.因此,即使是中等大小的应用程序也会在其代码中嵌入 ...
- matplotlib库之直方图
例题:假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据? 一些概念及问题: 把数据分 ...
- 并不对劲的复健训练-bzoj5253:loj2479:p4384:[2018多省联考]制胡窜
题目大意 给出一个字符串\(S\),长度为\(n\)(\(n\leq 10^5\)),\(S[l:r]\)表示\(S_l,S_{l+1}...,S_r\)这个子串.有\(m\)(\(m\leq 3\t ...