李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 左邻右舍
  • 博友圈
  • 关于我
    • 关于我
    • 网站地图
    • 网站统计
    • 另一个网站
    • 我的导航站
    • 赞助
  • 留言
  • 走心评论
  • 系列文章
  • Now
  • 每日心情
  • 论坛
  • 🚇开往
Destiny
自是人生长恨水长东
  1. 首页
  2. 转载
  3. 技术
  4. 正文

分布式锁-Zookeeper实现分布式锁

2019年11月11日 约 1,381 字5 分钟 30点热度 0人点赞 0条评论
本文最后更新于 2019年11月11日,距今已 2466 天,其中的信息可能已经发生变化,请注意甄别。

如何用Zookeeper实现分布式锁?

在学习分布式锁之前,需要首先了解一下Zookeeper的[临时顺序节点]。

什么是临时顺序节点?

让我们来回顾一下Zookeeper节点的概念:

自动草稿

Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Znode。

Znode分为四种类型:

1.持久节点 (PERSISTENT)

默认的节点类型。创建节点的客户端与zookeeper断开连接后,该节点依旧存在 。

2.持久节点顺序节点(PERSISTENT_SEQUENTIAL)

所谓顺序节点,就是在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号:

自动草稿

3.临时节点(EPHEMERAL) 

和持久节点相反,当创建节点的客户端与zookeeper断开连接后,临时节点会被删除。

自动草稿
自动草稿
自动草稿

4.临时顺序节点(EPHEMERAL_SEQUENTIAL) 
顾名思义,临时顺序节点结合和临时节点和顺序节点的特点:在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号;当创建节点的客户端与Zookeeper断开连接后,临时节点会被删除。

那临时顺序节点和Zookeeper的分布式锁有什么关系呢?

Zookeeper分布式锁的原理

Zookeeper分布式锁恰恰应用了临时顺序节点。具体如何实现呢?让我们来看一看详细步骤:

获取锁

首先,在Zookeeper当中创建一个持久节点ParentLock。当第一个客户端想要获得锁时,需要在ParentLock这个节点下面创建一个临时顺序节点 Lock1。

自动草稿

之后,Client1查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock1是不是顺序最靠前的一个。如果是第一个节点,则成功获得锁。

自动草稿

这时候,如果再有一个客户端 Client2 前来获取锁,则在ParentLock下载再创建一个临时顺序节点Lock2。

自动草稿

Client2查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock2是不是顺序最靠前的一个,结果发现节点Lock2并不是最小的。

于是,Client2向排序仅比它靠前的节点Lock1注册Watcher,用于监听Lock1节点是否存在。这意味着Client2抢锁失败,进入了等待状态。

自动草稿

这时候,如果又有一个客户端Client3前来获取锁,则在ParentLock下载再创建一个临时顺序节点Lock3。

自动草稿

Client3查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock3是不是顺序最靠前的一个,结果同样发现节点Lock3并不是最小的。

于是,Client3向排序仅比它靠前的节点Lock2注册Watcher,用于监听Lock2节点是否存在。这意味着Client3同样抢锁失败,进入了等待状态。

自动草稿

这样一来,Client1得到了锁,Client2监听了Lock1,Client3监听了Lock2。这恰恰形成了一个等待队列,很像是Java当中ReentrantLock所依赖的AQS(AbstractQueuedSynchronizer)。

获得锁的过程大致就是这样,那么Zookeeper如何释放锁呢?

释放锁的过程很简单,只需要释放对应的子节点就好。

释放锁

释放锁分为两种情况:

1.任务完成,客户端显示释放

当任务完成时,Client1会显示调用删除节点Lock1的指令。

自动草稿

2.任务执行过程中,客户端崩溃

获得锁的Client1在任务执行过程中,如果Duang的一声崩溃,则会断开与Zookeeper服务端的链接。根据临时节点的特性,相关联的节点Lock1会随之自动删除。

自动草稿

由于Client2一直监听着Lock1的存在状态,当Lock1节点被删除,Client2会立刻收到通知。这时候Client2会再次查询ParentLock下面的所有节点,确认自己创建的节点Lock2是不是目前最小的节点。如果是最小,则Client2顺理成章获得了锁。

自动草稿

同理,如果Client2也因为任务完成或者节点崩溃而删除了节点Lock2,那么Client3就会接到通知。

自动草稿

最终,Client3成功得到了锁。

自动草稿

使用Zookeeper实现分布式锁的大致流程就是这样。那么使用Zookeeper实现的分布式锁和Redis实现的分布式锁相比有什么优势和劣势呢?

下面总结一下他们各自的优劣。

分布式锁 优点 缺点
Zookeeper 1.有封装好的框架,容易实现

2.有等待锁的队列,大大提升抢锁效率。

添加和删除节点性能较低
Redis Set和Del指令性能较高 1.实现复杂,需要考虑超时,原子性,误删等情形。

2.没有等待锁的队列,只能在客户端自旋来等待,效率低下。

有人说Zookeeper实现的分布式锁支持可重入,Redis实现的分布式锁不支持可重入,这是错误的观点。两者都可以在客户端实现可重入逻辑。

关于Zookeeper分布式锁的内容就介绍到这里啦。

原文链接:https://blog.csdn.net/kongmin_123/article/details/82081953

除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.lifengdi.com/transport/1532

推荐阅读

  • ThreadLocal如何解决内存泄漏问题
  • ZooKeeper 的选举机制,你了解多少?
  • 详解 ZooKeeper 数据持久化
  • 分布式锁-Java常用技术方案
  • Redisson分布式锁的watch dog自动续期机制
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: JAVA Zookeeper 分布式 分布式锁
最后更新:2019年11月11日

岁月同一天 8 月 12 日

回望过去的今天,你在写什么

  • 6 年前 2020年8月12日
    jstat命令使用(JDK1.8)

    概述 jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下: jstat [-命令选项] [vm…

相关文章
  • 透过现象看本质:Java类动态加载和热替换2021年1月22日
  • SpringBoot集成Redis,从Redis中获取数据为null,但实际上Redis中是存在对应的数据的,是什么原因导致的呢?2021年1月19日
  • 解锁 Java 开发全流程效率:17 个必备工具深度指南2025年10月14日
  • Spring WebFlux深度解析:异步非阻塞架构与实战落地指南2025年12月15日
  • 结合Apollo配置中心实现日志级别动态配置2021年12月29日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复
…

文章评论

还没有评论,快来抢沙发吧~

不将沉重累坠的银元装在怀中,来自讨无谓的苦吃。

听点儿音乐吧 朋友~
文章目录
最新 热点 随机
最新 热点 随机
Kratos+ v1.1.16版本更新说明 WorkBuddy介绍 Kratos+ v1.1.14版本更新说明 Spring Boot 指定外部配置文件的方式 Spring Boot 配置加载优先级总结 Claude Fable 5(claude-fable-5)深度详解
给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能AI时代,个人技术博客的出路在哪里?增加了两套复古皮肤-牛皮纸、千禧网页这个域名注册整整十年了,十年时间,真快啊Kratos+ v1.1.14版本更新说明WordPress实现用户评论等级排行榜插件
使用shell脚本统一修改maven项目的版本 图数据库选型:Neo4j、Janus、HugeGraph 今晚,回家过年! ElasticSearch入门-基本概念介绍以及安装 SpringBoot 实现 RSA+AES 自动接口解密 Kafka常见面试题(一)
最近评论
李锋镝 发布于 2 天前(08月10日) 等我搞一个数据转换的插件~
李锋镝 发布于 2 天前(08月10日) 精美可担不起~😂
李锋镝 发布于 2 天前(08月10日) PHP是世界上最伟大的语言=。=
Hary 发布于 3 天前(08月09日) 我都想用了,但是是ty,转换有点麻烦
老张博客 发布于 4 天前(08月08日) 做的越来越精美了,好看。
标签聚合
Spring JAVA K8s SQL Claude Redis JVM 设计模式 分布式 MySQL IDEA 架构 ElasticSearch 日常 SpringBoot AI编程 AI 数据库 WordPress 多线程
友情链接
  • Serendipity
  • 老张博客
  • 韩小韩博客
  • Mr.Sun的博客
  • 九仞之行
  • 志文工作室
  • 风渡言
  • 知向前端
  • 拾趣博客导航
  • Honesty
  • 瓦匠个人小站
  • 旧时繁华
  • 彬红茶日记
  • 懋和道人
  • 临窗旋墨
  • 搬砖日记
  • 林羽凡
  • 哥斯拉
  • 韩情脉脉
  • 皮皮社

COPYRIGHT © 2026 lifengdi.com. ALL RIGHTS RESERVED.

正在博友圈履约中

域名年龄

Theme Kratos+ By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号