如何用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 ...
随机推荐
- this、call和apply、bind
this关键字: JavaScript的this关键字,总是指向一个对象,具体指向哪个对象,是根据运行时函数指向环境动态绑定的.简单来说,this就是谁调用指向谁.具体使用中,this的指向,大致可以 ...
- Devices下设备的进程显示为问号的问题
adb shell getprop ro.debuggable 返回 ro.debuggable=0 说明这个机子的版本不是userdebug版本,是user版本 只有这 ...
- LeetCode(21)题解:Merge Two Sorted Lists
https://leetcode.com/problems/merge-two-sorted-lists/ Merge two sorted linked lists and return it as ...
- 基于mqtt协议实现手机位置跟踪
Mqtt协议是物联网领域的一个标准协议,具有轻巧,对设备,带宽要求低,可靠稳定的特点,适合用来实现手机定位跟踪功能. 目前我初步搭建起来了整个可运行的框架,大致为如下思路:1.手机端通过位置服务,获取 ...
- Kubernetes实战阅读笔记--2、架构和部署
安装Kubernetes “本书准备了4台虚拟机(CentOS 7.0系统)用于部署Kubernetes运行环境,包括一个Etcd.一个Kubernetes Master和三个Kubernetes N ...
- MapReduce算法形式二:去重(HashSet)
案例二:去重(shuffle/HashSet等方法)shuffle主要针对的是key去重HashSet主要针对values去重
- Pattern: API Gateway / Backend for Front-End
http://microservices.io/patterns/apigateway.html Pattern: API Gateway / Backend for Front-End Contex ...
- bzoj3462: DZY Loves Math II
状态很差脑子不清醒了,柿子一直在推错.... ... 不难发现这个题实际上是一个完全背包 问题在于n太大了,相应的有质数的数量不会超过7个 假设要求sigema(1~plen)i pi*ci=n 的方 ...
- jQuery插件之ajaxFileUpload API文档
ajaxFileUpload是一个异步上传文件的jQuery插件. 语法:$.ajaxFileUpload([options]) options参数说明: 1.url 上传处理程序地址. 2,fil ...
- windwo访问linux文件夹方法
windwo访问linux文件夹:是通过linux的samba来实现的: 安装samba需要安装samba-client.samba-common.smaba3个包. 一:安装rpm 现有一个服务器l ...