[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 SetDel的性能比较高(毕竟键值数据库,Hash) 1.实现复杂,需要考虑原子性,误删等情况.
2.没有等待锁的机制,只能通过客户端的自旋来等锁,效率低下.

9: https://www.funtl.com/assets/Lusifer2018101900098]: https://www.funtl.com/assets/Lusifer201810190008.png

Zookeeper是如何实现分布式锁的的更多相关文章

  1. zookeeper适用场景:分布式锁实现

    问题导读:1.zookeeper如何实现分布式锁?2.什么是羊群效应?3.zookeeper如何释放锁? 在zookeeper应用场景有关于分布式集群配置文件同步问题的描述,设想一下如果有100台机器 ...

  2. 服务注册中心之ZooKeeper系列(三) 实现分布式锁

    通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...

  3. zookeeper【5】分布式锁

    我们常说的锁是单进程多线程锁,在多线程并发编程中,用于线程之间的数据同步,保护共享资源的访问.而分布式锁,指在分布式环境下,保护跨进程.跨主机.跨网络的共享资源,实现互斥访问,保证一致性. 架构图: ...

  4. 基于zookeeper或redis实现分布式锁

    前言 在分布式系统中,分布式锁是为了解决多实例之间的同步问题.例如master选举,能够获取分布式锁的就是master,获取失败的就是slave.又或者能够获取锁的实例能够完成特定的操作. 目前比较常 ...

  5. 基于ZooKeeper的三种分布式锁实现

    [欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 今天介绍基于ZooKeeper的分布式锁的简单实现,包括阻塞锁和非阻塞锁.同时增加了网上很少介绍的基于节点的非阻塞锁实现,主 ...

  6. Zookeeper绍二(分布式锁介)

    一.为什么会有分布式锁? 在多线程环境下,由于上下文的切换,数据可能出现不一致的情况或者数据被污染,我们需要保证数据安全,所以想到了加锁. 所谓的加锁机制呢,就是当一个线程访问该类的某个数据时,进行保 ...

  7. 跟着实例学习ZooKeeper的用法: 分布式锁

    锁 分布式的锁全局同步, 这意味着任何一个时间点不会有两个客户端都拥有相同的锁. 可重入锁Shared Reentrant Lock 首先我们先看一个全局可重入的锁. Shared意味着锁是全局可见的 ...

  8. Zookeeper系列3 实现分布式锁

    基本思路 1 client调用create()方法创建“/locks/_lock_”临时顺序节点,注意节点类型是EPHEMERAL_SEQUENTIAL 2 client调用getChildren(& ...

  9. ZooKeeper 分布式锁实现

    1 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问. 2 ...

随机推荐

  1. JavaScript的函数(一)

    ,1,在javascript中,函数即对象.函数里面的参数可以是个函数,例如: data.sort(function(a,b){return a-b;}) 函数的返回值,return语句导致函数停止执 ...

  2. nes 红白机模拟器 第6篇 声音支持

    InfoNES 源码中并没有包含 linux 的声音支持. 但提供 wince 和 win 的工程,文件,通过分析,win 的 DirectSound 发声,在使用 linux ALSA 实现. 先使 ...

  3. TypeScript Jest 调试

    本文简要介绍了如何在 Jest 单元测试中利用 Chrome Node DevTools 来辅助调试. 背景 代码是 TS 写的 所测功能无 UI 界面,出现Bug后不容易定位 用 console 式 ...

  4. 简说Python之IO

    闺女,你在玩电脑什么游戏? 爸爸,我在玩植物大战僵尸呢. 闺女,你知道什么是输入输出设备吗? 爸爸,??? 你看,咱们的键盘和鼠标 ,就是可以控制那些植物的工具.这些发出指令的就是输入设备.咱们可以用 ...

  5. 使用C#+EmguCV处理图像入门(一)

    首先我们先了解一下该库的一些相关信息 OpenCV(Open Source Computer Vision Library)是一个(开源免费)发行的跨平台计算机视觉库,可以运行在Linux.Windo ...

  6. 等价类计数:Burnside引理 & Polya定理

    提示: 本文并非严谨的数学分析,有很多地方是自己瞎口胡的,仅供参考.有错误请不吝指出 :p 1. 群 1.1 群的概念 群 \((S,\circ)\) 是一个元素集合 \(S\) 和一种二元运算 $ ...

  7. JAVA-阿里云短信服务

    1.引入相关依赖 <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> < ...

  8. docker系列详解<二>之常用命令

    此篇我们以从docker运行一个tomcat为例,进行一下操作: 拉取镜像 查看镜像 创建容器 查看运行状态 进入退出容器 停止容器 重启容器 删除容器 删除镜像 1.拉取tomcat镜像: 1).查 ...

  9. Shell 截取字符串方法

    原文链接 方法1 "${varible##*string}" 从左向右截取最后一个string后的字符串 e.g. exampleString="abc//888//ab ...

  10. Uncovering thousands of new peptides with sequence-mask-search hybrid de novo peptide sequencing framework (使用序列掩码搜索结合肽段从头测序框架发现了数千个新肽段)-解读人:刘佳维

    期刊名:Molecular & Cellular Proteomics 发表时间:(2019年12月) IF:4.828 单位: 朱拉隆功大学 费城威斯塔研究所 物种:人 技术:de novo ...