当前位置: 首页 > news >正文

zookeeper 分布式锁_zookeeper分布式锁最完美实现Curator剖析

59544bbb7813faa58bf224f35195c316.png

zookeeper分布式锁基于zookeeper中有序节点实现分布有序锁等待队列,通过watch机制监听锁释放,大大提升抢锁效率,避免自旋等锁,浪费cpu资源,同时只watch前一个节点可避免锁释放之后通知所有节点重新竞争锁导致的羊群效应。

curator基于zookeeper实现了InterProcessMutex(分布式可重入排它锁)、InterProcessSemaphoreMutex(分布式排它锁)、InterProcessReadWriteLock(分布式读写锁)、InterProcessMultiLock(将多个锁作为单个实体管理的容器)四种不同的锁实现,本文将介绍InterProcessMutex的实现原理。

3b5e4c585c4e7aa8e333e1be26e2bff2.png

实现步骤

(1)在根节点(持久化节点,eg:/lock)下创建临时有序节点。

(2)获取根节点下所有子节点,判断上一步中创建的临时节点是否是最小的节点。

是:加锁成功不是:加锁失败,对前一个节点加watch,收到删除消息后,加锁成功。(3)执行被锁住的代码块。

(4)删除自己在根节点下创建的节点,解锁成功。

加锁

96e8df715d431c7a847230376e2ea0a6.png

InterProcessMutex类acquire()方法通过调用internalLock()方法完成加锁操作。

(1)首先判断该线程是否已经获取锁,如果已经获取锁lockcount加一,加锁成功。该步骤支持锁重入。

(2)调用attemptlock()方法获取锁。

(3)获取锁成功后向threadData中添加数据,记录该线程已经获取锁。

继续分析attemptlock()方法

40c09bafdb3db333db65c977f20bcadd.png

(1)ourPath = driver.createsTheLock(client, path, localLockNodeBytes);创建临时有序节点。

(2)hasTheLock = internalLockLoop(startMillis, millisToWait, ourPath);判断上一步中创建的临时节点是否是根节点下最小的节点。如果是返回true,加锁成功。

继续分析internalLockLoop()方法

efdf90a1edb43b8fcb0a66e2f156fcd5.png

(1)进入循环,获取根节点下面所有子节点,判断上一步中创建的临时节点是否是根节点下最小的节点。如果是直接返回。

(2)对当前节点前一个节点加watch。

(3)调用wait()方法阻塞。

解锁

890010aca37bd6202366b1d0165b796f.png

InterProcessMutex类release()方法完成解锁操作。

(1)判断是否存在锁重入的情况,如果存在锁重入,lockcount减一,如果lockcount大于0直接返回;

(2)调用releaseLock()方法完成解锁操作。

继续继续分析releaseLock()方法。

3018a8c362cce28f6f522ca934244d91.png

releaseLock()调用deleteOurPath()方法将临时节点删除。删除后watch触发,调用notifyFromWatcher()方法执行notifyAll()方法,将线程唤醒继续执行操作。

总结

zookeeper集群使用zap协议来保证集群之间数据的一致性,频繁的进行写、监听操作将对zk集群产生较大压力,所以不推荐大家使用。

需要更多学习资料或是面试题可以私信我回复[资料]~

原文链接:https://baijiahao.baidu.com/s?id=1649547145421332925&wfr=spider&for=pc

相关文章:

  • 南昌
  • 思科wlc产品文档_基于Catalyst 9800 无线控制器的思科OEAP远程办公解决方案
  • 留记
  • ubuntu golang指定glibc版本_Go Lang 开发笔记《使用 Go Lang 搭建一个 Web 服务!》
  • 装机后进不了bios_是生产力也是游戏主力,12.7升A4风冷小钢炮装机体验
  • 差了点什么呢?
  • 黑盒测试和白盒测试_黑盒测试是什么及其测试方法
  • kmem 反编译linux内核_Linux 内核 VS 内存碎片 (上)
  • 总有一些人可以超越死亡——leo荐书(5)
  • 【转】为什么我认为每个程序员都应该用Mac OS X?
  • 用yacc编写的算术运算计算器_Android版科学计算器 Casio business 下载
  • 【转】开发人员为何应该使用 Mac OS X 兼 OS X 小史
  • ps 去掉一个人_电脑没有ps软件?只需要这个网站就能帮你搞定
  • rs多个设备同时传输_华为账号真的能同时登陆多个设备吗?华为官方的介绍来了...
  • dubbo invoke 日期参数怎么传_每日一技|巧用 Telnet 调试 Dubbo 服务
  • 【5+】跨webview多页面 触发事件(二)
  • Asm.js的简单介绍
  • HTTP那些事
  • in typeof instanceof ===这些运算符有什么作用
  • iOS 系统授权开发
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JAVA SE 6 GC调优笔记
  • JavaScript DOM 10 - 滚动
  • Js基础知识(一) - 变量
  • Linux gpio口使用方法
  • MobX
  • Python3爬取英雄联盟英雄皮肤大图
  • yii2权限控制rbac之rule详细讲解
  • 和 || 运算
  • 开源SQL-on-Hadoop系统一览
  • 前端技术周刊 2019-02-11 Serverless
  • 入手阿里云新服务器的部署NODE
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 一个项目push到多个远程Git仓库
  • 责任链模式的两种实现
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • "无招胜有招"nbsp;史上最全的互…
  • (11)MSP430F5529 定时器B
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (C语言)fgets与fputs函数详解
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (solr系列:一)使用tomcat部署solr服务
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (十六)串口UART
  • (学习日记)2024.01.19
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .Net MVC + EF搭建学生管理系统
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .Net 垃圾回收机制原理(二)
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET下ASPX编程的几个小问题
  • @Autowired注解的实现原理
  • @FeignClient注解,fallback和fallbackFactory