如何用Zookeeper来实现分布式锁?
什么是Zookeeper临时顺序节点?
例如 :
/
动物 植物
猫 仓鼠 荷花 松树
Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Zonde.
# Znode分为四种类型 :
1.持久节点(PERSISTENT)
默认的节点类型.创建节点的客户端与zookeeper断开连接后,该节点依旧存在.
2.持久节点顺序节点(PERSISTENT_SEQUENTIAL)
所谓顺序节点,就是在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号.
例如 :
仓鼠
仓鼠0001 仓鼠0002 仓鼠0003
3.临时节点(EPHEMERAL)
和持久节点相反,当创建节点的客户端与zookeeper断开连接后,临时节点会被删除 :
4.临时顺序节点(EPHEMERAL_SEQUENTIAL)
临时顺序节点结合了临时节点和顺序节点的特点 : 在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号 ; 当创建节点的客户端与zookeeper
断开连接后,临时节点会被删除.
# Zookeeper分布式锁的原理
Zookeeper分布式锁恰恰应用了临时顺序节点
## 获取锁 :
首先,在Zookeeper当中创建一个持久节点ParentLock.当第一个客户端想要获得锁时,需要在ParentLock这个节点下面创建一个临时顺序节点Lock1.
之后,Client1查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock1是不是顺序最靠前的一个.如果是第一个节点,则成功获得锁.
这时候,如果再有一个客户端Client2前来获取锁,则在ParentLock下再创建一个临时顺序节点Lock2.
Client2查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock2是不是顺序最靠前的一个,结果发现节点Lock2并不是最小的.
于是,Client2向排序仅比它靠前的节点Lock2注册Watcher,用于监听Lock1节点是否存在.这意味着Client2抢锁失败,进入了等待状态.
这时候,如果又有一个客户端Client3前来获取锁,则在ParentLock下再创建一个临时顺序节点Lock3.
Client3查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock3是不是顺序最靠前的一个,结果同样发现节点Lock3并不是最小的.
于是,Client3向排序仅比它靠前的节点Lock2注册Watcher,用于监听Lock2节点是否存在.这意味着Client3同样抢锁失败,进入了等待状态.
这样一来,Client1得到了锁,Client2监听了Lock1,Client3监听了Lock2.这恰恰形成了一个等待队列,很像是Java当中的ReentrantLock所依赖的AQS(AbstractQueuedSynchronizer)
## 释放锁 :
释放锁分为两种情况 :
1.任务完成,客户端显示释放
当任务完成时,Client1会显示调用删除节点Lock1的指令.
2.任务执行过程中,客户端崩溃
获得锁的Client1在任务执行过程中,如果Duang的一声崩溃则会断开与Zookeeper服务端的链接.根据临时节点的特性,相关联的节点Lock1会随之自动删除.
由于Client2一直监听着Lock1的存在状态,当Lock1节点被删除,Client2会立刻收到通知.这时候Client2会再次查询ParentLock下面的所有节点,确认自己创建
的节点Lock2是不是目前最小的节点.如果是最小,则Client2顺利成章获得锁.
同理,如果Client2也因为任务完成或者节点崩溃而删除了节点Lock2,那么Client3就会接到通知.最终,Client3成功得到了锁.
Zookeeper和Redis分布式锁的比较
Zookeeper的
优点 :
1.有封装好的框架,容易实现.
2.有等待锁的队列,大大提升抢锁效率.
缺点 :
1.添加和删除节点性能较低.
Redis
优点 : Set和Del指令的性能较高.
缺点 :
1.实现复杂,需要考虑超时,原子性,误删等情形.
2.没有等待锁的队列,只能在客户端自旋等锁,效率低下.
两者都可以在客户端实现可重入逻辑.
在Apache的开源框架Apache Curator中,包含了对Zookeeper分布式锁的实现,源码 : https://github.com/apache/curator/
如何用Zookeeper来实现分布式锁?的更多相关文章
- 基于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 ...
- 如何用redis正确实现分布式锁?
先把结论抛出来:redis无法正确实现分布式锁!即使是redis单节点也不行!redis的所谓分布式锁无法用在对锁要求严格的场景下,比如:同一个时间点只能有一个客户端获取锁. 首先来看下单节点下一般r ...
随机推荐
- hihoCoder 1234 fractal
#1234 : Fractal 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 This is the logo of PKUACM 2016. More specific ...
- 最简单的基于FFmpeg的AVDevice样例(读取摄像头)
=====================================================最简单的基于FFmpeg的AVDevice样例文章列表: 最简单的基于FFmpeg的AVDev ...
- 【iOS开源码】(1):CCLHTTPServer
我从没有见过比 CCLHTTPServer 更简单的 iOS HTTP server了.你甚至不用创建不论什么子类就可以使用它.对于大部分任务,这个小巧但强悍的server能够满足你的须要. 它简单到 ...
- Creo二次开发--内存清理函数
我们在处理模型文件时,总会遇到内存环境的清除问题.一个干净的Creo工作环境.是保证工作能顺利完毕的保障. ProMdlEraseNotDisplayed()函数提供了清除未显示模型的功能. 当须要循 ...
- Centos修改静态IP
vim /etc/sysconfig/network-scripts/ifcfg-eth0代开配置文件 写入 DEVICE=eth0 #描述网卡对应的设备别名,例如ifcfg-eth0的文件中它为et ...
- 初识跨终端Web
近期试读了<跨终端Web>这本书的部分章节,既为了拿到书,也为了记录下读后的收获的东西,这会是个非常好的习惯吧. 标题为"初识跨终端Web".对我来说最贴切了,在此之前 ...
- DRF 之 版本控制
1.版本控制是干什么用的,为什么要有版本? 我们都知道每一个程序都是有版本的.而且版本也会升级从v1升级到v2.v3.v4·····,但是我们不可能因为新版本出现旧版本就不去维护,因为用户有权选择不更 ...
- TreeSet实现Comparator接口的排序算法的分析
为了方便,用lambda表达式代替comparator接口 例子如下: public static void main(String[] args) { TreeSet<Integer> ...
- java上下文Context类
Context在Java中的出现是如此频繁,但其中文翻译"上下文"又是如此诡异拗口,因此导致很多人不是很了解Context的具体含义是指什么,所以很有必要来深究一下这词的含义. 先 ...
- iOS内存管理机制解析之MRC手动引用计数机制
前言: iOS的内存管理机制ARC和MRC是程序猿參加面试基本必问的问题,也是考察一个iOS基本功是 否扎实的关键,这样深入理解内存管理机制的重要性就不言而喻了. iOS内存管理机制发展史 iOS 5 ...