Zookeeper是如何实现分布式锁的
[toc]
Zookeeper是如何实现分布式锁的
标签 : Zookeeper 分布式
实现分布式锁要考虑的重要问题
1. 三个核心要素
加锁, 解锁, 锁超时
2. 三个问题
- 要保证原子性操作, 加锁和锁超时的操作要一次性执行完毕
- 防止误删锁
- 在误删的基础上, 加一个守护线程, 为锁续命.
什么是临时顺序节点
Zookeeper的数据存储结构就像是一棵树, 这棵树由节点组成, 这种节点叫做Znode. Znode分为四种类型.
1. 持久节点(Persistent)
默认的节点类型, 创建节点的客户端和Zookeeper断开连接之后, 该节点依旧存在.
2. 持久顺序节点(Persistent Sequential)
所谓顺序节点, 就是在创建节点的时候, Zookeeper根据节点的创建时间顺序给节点的名称进行编号.

3. 临时节点(Ephemeral)
和持久节点相反, 当创建节点的客户端与Zookeeper断开连接之后,临时节点会被删除.



4. 临时顺序节点(Ephemeral Sequential)
在创建节点时, Zookeeper根据创建的时间顺序给该节点名称进行编号; 当创建节点的客户端与Zookeeper断开连接之后,临时节点会被删除.
Zookeeper实现分布式锁的原理
上面已经说了Znode的四种类型, 其中最后一种类型 临时顺序节点 是最有利于实现Zookeeper分布式锁的.
1. 获取锁
- 首先, 在Zookeeper当中创建一个持久节点ParentLock. 当第一个客户端想要获得操作某项数据的锁的时候,需要在该持久节点之下简历一个临时顺序节点
Lock1.

- 之后,
客户端1查找ParentLock下面所有的临时顺序节点并按照大小排序, 判断自己所创建的节点Lock1是不是顺序最靠前的一个. 如果是第一个节点,则成功获得锁.

- 此时,
客户端2前来获取该项数据的锁, 则在ParentLock下再创建一个临时顺序节点Lock2.

客户端2查找ParentLock下面所有的临时顺序节点并排序,发现自己的Lock2节点并不是最靠前的. 于是客户端2向排序仅仅比它靠前的Lock1注册Watcher, 用于监听Lock1动态. 这意味着Lock2抢锁失败, 进入等待状态.

- 此时, 如果有一个
客户端3前来获取锁, 则在ParentLock下在创建一个临时顺序节点Lock3.

客户端3查找ParentLock下面所有的临时顺序节点并排序, 判断自己所创建的节点Lock3是不是顺序最靠前的一个, 结果发现Lock3不是最靠前的. 于是客户端3同样抢锁失败, 进入了等待状态.

- 这个时候
客户端1得到了锁,客户端2监听了客户端1,客户端3监听了客户端2. 这样刚好形成一个等待的队列.
2. 释放锁
释放锁有两种情况
2.1 任务完成, 客户端显示释放
- 当任务完成时,
客户端1会显示的调用删除节点Lock1的指令.

2.2 任务执行过程中, 客户端崩溃
- 获得锁的
客户端1在执行任务的过程中, 如果崩溃, 则会断开和Zookeeper服务器的链接, 根据临时节点的特性, 相关联的Lock1会随之自动删除.

3. 获得锁
- 由于
客户端2一直在监听Lock1的状态,这个时候发现Lock1注销了,客户端2会立即接收到通知. 这个时候客户端2会再次查询ParentLock下的所有节点, 确认自己所创建的节点是不是最小的节点, 如果是最小的则成功获得锁.

同理可推至
客户端3
总结
Zookeeper和Redis分布式锁的比较
| 分布式锁 | 优点 | 缺点 |
|---|---|---|
| Zookeeper | 1.有封装好的框架,容易实现. 2.有等待锁的机制( Watcher),可以提高抢锁的效率,好处多多 |
添加和删除节点的性能比较低 |
| Redis | Set和Del的性能比较高(毕竟键值数据库,Hash) |
1.实现复杂,需要考虑原子性,误删等情况. 2.没有等待锁的机制,只能通过客户端的自旋来等锁,效率低下. |
9: https://www.funtl.com/assets/Lusifer2018101900098]: https://www.funtl.com/assets/Lusifer201810190008.png
Zookeeper是如何实现分布式锁的的更多相关文章
- zookeeper适用场景:分布式锁实现
问题导读:1.zookeeper如何实现分布式锁?2.什么是羊群效应?3.zookeeper如何释放锁? 在zookeeper应用场景有关于分布式集群配置文件同步问题的描述,设想一下如果有100台机器 ...
- 服务注册中心之ZooKeeper系列(三) 实现分布式锁
通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...
- zookeeper【5】分布式锁
我们常说的锁是单进程多线程锁,在多线程并发编程中,用于线程之间的数据同步,保护共享资源的访问.而分布式锁,指在分布式环境下,保护跨进程.跨主机.跨网络的共享资源,实现互斥访问,保证一致性. 架构图: ...
- 基于zookeeper或redis实现分布式锁
前言 在分布式系统中,分布式锁是为了解决多实例之间的同步问题.例如master选举,能够获取分布式锁的就是master,获取失败的就是slave.又或者能够获取锁的实例能够完成特定的操作. 目前比较常 ...
- 基于ZooKeeper的三种分布式锁实现
[欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 今天介绍基于ZooKeeper的分布式锁的简单实现,包括阻塞锁和非阻塞锁.同时增加了网上很少介绍的基于节点的非阻塞锁实现,主 ...
- Zookeeper绍二(分布式锁介)
一.为什么会有分布式锁? 在多线程环境下,由于上下文的切换,数据可能出现不一致的情况或者数据被污染,我们需要保证数据安全,所以想到了加锁. 所谓的加锁机制呢,就是当一个线程访问该类的某个数据时,进行保 ...
- 跟着实例学习ZooKeeper的用法: 分布式锁
锁 分布式的锁全局同步, 这意味着任何一个时间点不会有两个客户端都拥有相同的锁. 可重入锁Shared Reentrant Lock 首先我们先看一个全局可重入的锁. Shared意味着锁是全局可见的 ...
- Zookeeper系列3 实现分布式锁
基本思路 1 client调用create()方法创建“/locks/_lock_”临时顺序节点,注意节点类型是EPHEMERAL_SEQUENTIAL 2 client调用getChildren(& ...
- ZooKeeper 分布式锁实现
1 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问. 2 ...
随机推荐
- iview的render函数使用
render渲染函数详解 https://www.cnblogs.com/weichen913/p/9676210.html iview表格的render函数作用是自定义渲染当前列,权限高于key,所 ...
- 写react项目要注意的事项
1,className一定是大写字母开头,例如:App-logo,App,App-header. 2,有关react元素的更新,唯一办法是创建新元素,然后重新将其传入ReactDOM.render() ...
- MySQL的万字总结(缓存,索引,Explain,事务,redo日志等)
hello,小伙伴们,好久不见,MySQL系列停更了差不多两个月了,也有小伙伴问我为啥不更了呢?其实我去看了MySQL的全集,准备憋个大招,更新篇长文(我不会告诉你是因为我懒的). 好了,话不多说,直 ...
- 幕布,workflowy的使用技巧
Q: 幕布免费用户导出文档为纯文本或opml: - 将文档Ctrl+C 复制到workflowy: - workflowy可以导出plain-text或opml: 注:已知这样的方法,注释的格式不会被 ...
- 我要打十个!详解建造者模式(builder pattern)
前言 "我要打十个",其实是我要打十个野怪! 这十个野怪呢,它们有不同的技能.装备和武器,长得也不一样.这里野怪是一个蛮复杂的对象,由各个不同的部分组成(技能.装备.武器等),不同 ...
- oracle中plsql练习题----查询姓为“SMITH”的员工信息,并输出其员工号、姓名、工资、部门号。 – –如果该员工不存在,则插入一条新记录,员工号为2012,员工姓名为“Smith”,工资为7500元,入职日期为“2002年3月5日”,部门号为50。 – –如果存在多个名“Smith”的员工,则输出所有名为“Smith”的员工号、姓名、工资、入职日期、部门号L。
一.思路:首先判断这个查询的是emp表,需要接收值,声明一个rowtype类型接收数据即可,第二是,存在exception,需要处理,exception中有两种异常,分别处理即可,分别输出即可. 二. ...
- C# 在DataGridView中,点击单元格调出 TreeView控件 或 ListBox控件
1.调出 TreeView控件 或 ListBox控件 private void deductGrid1_CellClick(object sender, DataGridViewCellEvent ...
- 题解 P1305 【新二叉树】
好像没有人搞\(\color{green}map\)反映,没有人用\(\color{green}map\)反映搞并查集! \(\color{green}map\)第一个好处是作为一个数组,可以开很大! ...
- Serpent.AI - 游戏代理框架(Python)
Serpent.AI - 游戏代理框架(Python) Serpent.AI是一个简单而强大的新颖框架,可帮助开发人员创建游戏代理.将您拥有的任何视频游戏变成一个成熟的实验的沙箱环境,所有这些都是熟悉 ...
- Spark使用jdbc时的并行度
Spark SQL支持数据源使用JDBC从其他数据库读取数据. 与使用JdbcRDD相比,应优先使用此功能. 这是因为结果以DataFrame的形式返回,并且可以轻松地在Spark SQL中进行处理或 ...