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


    前言

    一般工作中常用的分布式锁,就是基于 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

    相关推荐

    作者: 刘志航

    公众号:『 程序员小航 』

    版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Notes

  • 相关阅读:
    Working with WordprocessingML documents (Open XML SDK)
    How to Choose the Best Way to Pass Multiple Models in ASP.NET MVC
    Azure:Manage anonymous read access to containers and blobs
    Convert HTML to PDF with New Plugin
    location.replace() keeps the history under control
    On the nightmare that is JSON Dates. Plus, JSON.NET and ASP.NET Web API
    HTTP Modules versus ASP.NET MVC Action Filters
    解读ASP.NET 5 & MVC6系列(6):Middleware详解
    Content Negotiation in ASP.NET Web API
    Action Results in Web API 2
  • 原文地址:https://www.cnblogs.com/liuzhihang/p/15018897.html
Copyright © 2020-2023  润新知