一、写在前面

之前写过一篇文章(《拜托,面试请不要再问我Redis分布式锁的实现原理》),给大家说了一下Redisson这个开源框架是如何实现Redis分布式锁原理的,这篇文章再给大家聊一下ZooKeeper实现分布式锁的原理。

同理,我是直接基于比较常用的Curator这个开源框架,聊一下这个框架对ZooKeeper(以下简称zk)分布式锁的实现。

一般除了大公司是自行封装分布式锁框架之外,建议大家用这些开源框架封装好的分布式锁实现,这是一个比较快捷省事儿的方式。

二、ZooKeeper分布式锁机制

接下来我们一起来看看,多客户端获取及释放zk分布式锁的整个流程及背后的原理。

首先大家看看下面的图,如果现在有两个客户端一起要争抢zk上的一把分布式锁,会是个什么场景?

如果大家对zk还不太了解,建议先百度一下,快速了解一些基本概念,比如zk有哪些节点类型等等。

参见上图。zk里有一把锁,这个锁就是zk上的一个节点。然后呢,两个客户端都要来获取这个锁,具体是怎么来获取呢?

咱们就假设客户端A抢先一步,对zk发起了加分布式锁的请求,这个加锁请求是用到了zk中的一个特殊的概念,叫做“临时顺序节点”。

简单来说,就是直接在"my_lock"这个锁节点下,创建一个顺序节点,这个顺序节点有zk内部自行维护的一个节点序号。

比如说,第一个客户端来搞一个顺序节点,zk内部会给起个名字叫做:xxx-000001。然后第二个客户端来搞一个顺序节点,zk可能会起个名字叫做:xxx-000002。大家注意一下,最后一个数字都是依次递增的,从1开始逐次递增。zk会维护这个顺序。

所以这个时候,假如说客户端A先发起请求,就会搞出来一个顺序节点,大家看下面的图,Curator框架大概会弄成如下的样子:

大家看,客户端A发起一个加锁请求,先会在你要加锁的node下搞一个临时顺序节点,这一大坨长长的名字都是Curator框架自己生成出来的。

然后,那个最后一个数字是"1"。大家注意一下,因为客户端A是第一个发起请求的,所以给他搞出来的顺序节点的序号是"1"。

接着客户端A创建完一个顺序节点。还没完,他会查一下"my_lock"这个锁节点下的所有子节点,并且这些子节点是按照序号排序的,这个时候他大概会拿到这么一个集合:

接着客户端A会走一个关键性的判断,就是说:唉!兄弟,这个集合里,我创建的那个顺序节点,是不是排在第一个啊?

如果是的话,那我就可以加锁了啊!因为明明我就是第一个来创建顺序节点的人,所以我就是第一个尝试加分布式锁的人啊!

bingo!加锁成功!大家看下面的图,再来直观的感受一下整个过程。

接着假如说,客户端A都加完锁了,客户端B过来想要加锁了,这个时候他会干一样的事儿:先是在"my_lock"这个锁节点下创建一个临时顺序节点,此时名字会变成类似于:

大家看看下面的图:

客户端B因为是第二个来创建顺序节点的,所以zk内部会维护序号为"2"。

接着客户端B会走加锁判断逻辑,查询"my_lock"锁节点下的所有子节点,按序号顺序排列,此时他看到的类似于:

同时检查自己创建的顺序节点,是不是集合中的第一个?

明显不是啊,此时第一个是客户端A创建的那个顺序节点,序号为"01"的那个。所以加锁失败

加锁失败以后,客户端B就会通过ZK的API,对他的上一个顺序节点加一个监听器。zk天然就可以实现对某个节点的监听。

我们举例说明,客户端B的顺序节点是:

他的上一个顺序节点,不就是下面这个吗?

也就是客户端A创建的那个顺序节点!

所以,客户端B会对:

这个节点加一个监听器,监听这个节点是否被删除等变化!

说了那么多,老规矩,给大家来一张图,直观的感受一下:

接着,客户端A加锁之后,可能处理了一些代码逻辑,然后就会释放锁。那么,释放锁是个什么过程呢?

其实很简单,就是把自己在zk里创建的那个顺序节点,也就是:

这个节点给删除。

删除了那个节点之后,zk会负责通知监听这个节点的监听器,也就是客户端B之前加的那个监听器,说:兄弟,你监听的那个节点被删除了,有人释放了锁。

我们一起来看看下面的图,体会一下这个过程:

此时客户端B的监听器感知到了上一个顺序节点被删除,也就是排在他之前的某个客户端释放了锁。

此时,就会通知客户端B重新尝试去获取锁,也就是获取"my_lock"节点下的子节点集合,此时为:

集合里此时只有客户端B创建的唯一的一个顺序节点了!

然后呢,客户端B一判断,发现自己居然是集合中的第一个顺序节点,bingo!可以加锁了!直接完成加锁,运行后续的业务代码即可,运行完了之后再次释放锁。

最后,再给大家来一张图,大伙儿顺着图仔细的捋一捋这整个过程:

三、总结

其实如果有客户端C、客户端D等N个客户端争抢一个zk分布式锁,原理都是类似的。

  • 大家都是上来直接创建一个锁节点下的一个接一个的临时顺序节点

  • 如果自己不是第一个节点,就对自己上一个节点加监听器

  • 只要上一个节点释放锁,自己就排到前面去了,相当于是一个排队机制。

而且用临时顺序节点的另外一个用意就是,如果某个客户端创建临时顺序节点之后,不小心自己宕机了也没关系,zk感知到那个客户端宕机,会自动删除对应的临时顺序节点,相当于自动释放锁,或者是自动取消自己的排队。

最后,咱们来看下用Curator框架进行加锁和释放锁的一个过程:

其实用开源框架就是这点好,方便。这个Curator框架的zk分布式锁的加锁和释放锁的实现原理,其实就是上面我们说的那样子。

但是如果你要手动实现一套那个代码的话。还是有点麻烦的,要考虑到各种细节,异常处理等等。所以大家如果考虑用zk分布式锁,可以参考下本文的思路。

彻底讲清楚ZooKeeper分布式锁的实现原理【石杉的架构笔记】相关推荐

  1. zookeeper 分布式锁原理

    zookeeper 分布式锁原理: 1 大家也许都很熟悉了多个线程或者多个进程间的共享锁的实现方式了,但是在分布式场景中我们会面临多个Server之间的锁的问题,实现的复杂度比较高.利用基于googl ...

  2. 分布式锁原理——redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  3. 关于分布式锁原理的一些学习与思考:redis分布式锁,zookeeper分布式锁

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 作者:队长给我球. 出处:https://w ...

  4. zookeeper 分布式锁_关于redis分布式锁,zookeeper分布式锁原理的一些学习与思考

    编辑:业余草来源:https://www.xttblog.com/?p=4946 首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法 ...

  5. redis cluster 分布式锁_关于分布式锁原理的一些学习与思考redis分布式锁,zookeeper分布式锁...

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

  6. zookeeper分布式锁原理及实现

    前言 本文介绍下 zookeeper方式 实现分布式锁 原理简介 zookeeper实现分布式锁的原理就是多个节点同时在一个指定的节点下面创建临时会话顺序节点,谁创建的节点序号最小,谁就获得了锁,并且 ...

  7. Zookeeper分布式锁原理

    1.分布式锁介绍 单机应用开发,涉及并发同步的时候,我们往往采用synchronized 或者Lock的方式来解决多线程间的代码同步问题,这时多线程的运行都是在同一个JVM之下,没有任何问题. 但当我 ...

  8. 关于redis分布式锁,zookeeper分布式锁原理的一些学习与思考

    编辑:业余草 来源:https://www.xttblog.com/?p=4946 首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方 ...

  9. 快来学习Redis 分布式锁的背后原理

    以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情况是这 ...

  10. 还不知道 Redis 分布式锁的背后原理?还不赶快学习一下

    前言 以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情 ...

最新文章

  1. Mac使用自带的屏幕共享实现VNC连接KVM时需要输入密码的问题解决
  2. gdcm::DummyValueGenerator的测试程序
  3. HtmlTextWriter学习
  4. oracle排序函数性能,oracle排序函数
  5. 【C语言深入】[002] valotile 关键字:
  6. Java NIO AIO编程
  7. rstudio查询命令_Rstudio支持可视化的Markdown编辑了?
  8. 使用 Ajax 调用 SOAP Web 服务,第 1 部分: 构建 Web 服务客户机
  9. heartbeat双机热备配置(适用centos6\rhel6)
  10. PTN OAM交互接口设计
  11. 微信小程序模板消息(带流程图)
  12. 电商之 团购与B2C模式以及B2B2C模式对比
  13. 苹果弃用 3D Touch!
  14. vasp计算压电系数_求助DFTP算出来的压电系数
  15. 超详细!动态规划详解分析(典型例题分析和对比,附源码)
  16. 如何使 一个 div 居中显示
  17. shareSDK判断是否安装微博客户端、qq客户端不好使,或分享无法调起微博、qq客户端。
  18. ntp时间同步,各种配置方法
  19. Kuick:创业大军中脱颖而出的少数派
  20. jfinal框架之登录注册

热门文章

  1. J2EE学习篇之--Struts1详解
  2. (二十六)树莓派3B+ 获取HMC5883L的磁场数据
  3. 如何把微信朋友圈的小视频转发到自己的朋友圈
  4. 什么样的固定资产管理系统才能满足企业需求
  5. 基于YOLO的新型RGB-D融合方法对行人进行检测和3D定位
  6. android cardview,安卓 CardView 妙用
  7. CCFCSP历年认证考试真题解答汇总(已解决20道,持续更新ing)
  8. ensp的下载与安装教程
  9. python机器视觉培训——Python的安装
  10. SSH智能社区住户信息管理系统