ZooKeeper 分布式锁 Curator 源码 01:可重入锁

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 一般工作中常用的分布式锁,就是基于 Redis 和 ZooKeeper,前面已经介绍完了 Redisson 锁相关的源码,下面一起看看基于 ZooKeeper 的锁。也就是 Curator 这个框架。

前言


一般工作中常用的分布式锁,就是基于 Redis 和 ZooKeeper,前面已经介绍完了 Redisson 锁相关的源码,下面一起看看基于 ZooKeeper 的锁。也就是 Curator 这个框架。

网络异常,图片无法展示
|

Curator 的锁也分为很多种,本文分析共享可重入锁。

考虑到如果文章篇幅较长,不太适合阅读,所以对文章做了适当的拆分。


环境配置

网络异常,图片无法展示
|

本机三个节点

版本:3.7.0 系统:macOS 安装方式:brew install zookeeper Curator Maven 依赖版本:5.1.0

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>5.1.0</version>
</dependency>


加锁示例

网络异常,图片无法展示
|

详细信息可参考官方文档


加锁前

网络异常,图片无法展示
|

在加锁之前,ZooKeeper 仅有一个节点 /zookeeper


加锁中

/locks/lock_01 路径上加锁。

网络异常,图片无法展示
|

加锁之后:

  1. 创建了一个 /locks/lock_01 的持久节点,节点下有一个子节点 _c_cc4fc045-5a1e-4378-b3c7-8a8d3fb9a37c-lock-0000000000
  2. 节点 /locks/lock_01/_c_cc4fc045-5a1e-4378-b3c7-8a8d3fb9a37c-lock-0000000000 是临时节点
  3. 节点 /locks/lock_01/_c_cc4fc045-5a1e-4378-b3c7-8a8d3fb9a37c-lock-0000000000 的数据是机器 IP 地址


加锁源码

PS:下面代码截图中的代码风格就是 Curator 源码的代码风格。


入口

InterProcessMutex#internalLock

网络异常,图片无法展示
|

开始先从 threadData 中获取当前线程,这里肯定是没有的,所以进入 attemptLock 方法。

本方法中还包含了锁重入的逻辑,后面也会介绍。


加锁

LockInternals#attemptLock

网络异常,图片无法展示
|

核心部分就是这两行:

  1. createsTheLock 创建临时顺序节点
  2. internalLockLoop 判断是否创建成功


创建临时顺序节点

StandardLockInternalsDriver#createsTheLock

网络异常,图片无法展示
|

可以看出节点的 mode 是 CreateMode.EPHEMERAL_SEQUENTIAL,表示这是一个临时


顺序节点!

进入 CreateBuilderImpl#forPath(java.lang.String, byte[])

网络异常,图片无法展示
|

client.getDefaultData() 就是本机 IP 地址。

这个 adjustPath 方法看名字就是在调整路径之类的。会生成一个 UUID 拼接到 /locks/lock_01 中,变成 /locks/lock_01/_c_UUID-lock-

因为创建的是临时顺序节点,所以会自动在后面添加顺序,最终变为 /locks/lock_01/_c_UUID-lock-0000000000

具体创建节点是在 CreateBuilderImpl#pathInForeground 中。

网络异常,图片无法展示
|

  1. 创建临时节点,如果路径存在,会创建成功,如果路径不存在会创建失败;
  2. 创建失败后,先创建路径,再创建节点。


总结


本篇文章主要介绍了基于 ZooKeeper 的分布式锁框架 Curator 的使用,以及加锁流程,源码分析。

下面对内容做下总结:

网络异常,图片无法展示
|

重点需要关注的是:

  1. 基于 ZooKeeper 的分布式锁,是使用的临时顺序节点,父节点是持久节点;
  2. 创建临时节点时,父节点不存在,会先创建父节点(路径);
  3. 锁的组成结构为:对 /locks/lock_01 加锁,实际锁住的是 /locks/lock_01/_c_UUID-lock-序号,举例为 /locks/lock_01/_c_cc4fc045-5a1e-4378-b3c7-8a8d3fb9a37c-lock-0000000000
相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
1月前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
124 2
|
2月前
|
监控 Dubbo 前端开发
快速入门分布式系统与Dubbo+zookeeper Demo
快速入门分布式系统与Dubbo+zookeeper Demo
42 0
|
2月前
|
NoSQL 算法 安全
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
Redlock 算法-主从redis分布式锁主节点宕机锁丢失的问题
160 0
|
2月前
|
监控 NoSQL Java
Zookeeper分布式锁
Zookeeper分布式锁
90 1
|
5天前
|
存储 大数据 Apache
深入理解ZooKeeper:分布式协调服务的核心与实践
【5月更文挑战第7天】ZooKeeper是Apache的分布式协调服务,确保大规模分布式系统中的数据一致性与高可用性。其特点包括强一致性、高可用性、可靠性、顺序性和实时性。使用ZooKeeper涉及安装配置、启动服务、客户端连接及执行操作。实际应用中,面临性能瓶颈、不可伸缩性和单点故障等问题,可通过水平扩展、集成其他服务和多集群备份来解决。理解ZooKeeper原理和实践,有助于构建高效分布式系统。
|
22天前
|
Java API Apache
ZooKeeper【基础 03】Java 客户端 Apache Curator 基础 API 使用举例(含源代码)
【4月更文挑战第11天】ZooKeeper【基础 03】Java 客户端 Apache Curator 基础 API 使用举例(含源代码)
33 11
|
1月前
|
Java 网络安全 Apache
搭建Zookeeper集群:三台服务器,一场分布式之舞
搭建Zookeeper集群:三台服务器,一场分布式之舞
47 0
|
1月前
|
缓存 NoSQL 数据库
关于高并发下缓存失效的问题(本地锁 && 分布式锁 && Redission 详解)
关于高并发下缓存失效的问题(本地锁 && 分布式锁 && Redission 详解)
151 0
|
4月前
|
消息中间件 Java 网络安全
JAVAEE分布式技术之Zookeeper的第一次课
JAVAEE分布式技术之Zookeeper的第一次课
71 0
|
4月前
|
监控 Dubbo Java
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
63 0