• 中文
    • English
  • 注册
  • 查看作者
  • 分布式锁实战:基于Zookeeper的实现

    1. Zookeeper概述

    Zookeeper(后续简称ZK)是一个分布式的,开放源码的分布式应用程序协调服务,通常以集群模式运转,其协调能力可以理解为是基于观察者设计模式来实现的;ZK服务会使用Znode存储使用者的数据,并将这些数据以树形目录的形式来组织管理,支持使用者以观察者的角色指定自己关注哪些节点\数据的变更,当这些变更发生时,ZK会通知其观察者;为满足本篇目标所需,着重介绍以下几个关键特性:

    • 数据组织:数据节点以树形目录(类似文件系统)组织管理,每一个节点中都会保存数据信息和节点信息。

    分布式锁实战:基于Zookeeper的实现

    • 集群模式:通常是由3、5个基数实例组成集群,当超过半数服务实例正常工作就能对外提供服务,既能避免单点故障,又尽量高可用,每个服务实例都有一个数据备份,以实现数据全局一致

    分布式锁实战:基于Zookeeper的实现

    • 顺序更新:更新请求都会转由leader执行,来自同一客户端的更新将按照发送的顺序被写入到ZK,处理写请求创建Znode时,Znode名称后会被分配一个全局唯一的递增编号,可以通过顺序号推断请求的顺序,利用这个特性可以实现高级协调服务

    分布式锁实战:基于Zookeeper的实现

    • 监听机制:给某个节点注册监听器,该节点一旦发生变更(例如更新或者删除),监听者就会收到一个Watch Event,可以感知到节点\数据的变更

    分布式锁实战:基于Zookeeper的实现

    • 临时节点:session链接断开临时节点就没了,不能创建子节点(很关键)

    ZK的分布式锁正是基于以上特性来实现的,简单来说是:

    • 临时节点:用于支撑异常情况下的锁自动释放能力

    • 顺序节点:用于支撑公平锁获取锁和排队等待的能力

    • 监听机制:用于支撑抢锁能力

    • 集群模式:用于支撑锁服务的高可用

    2. 加解锁的流程描述

    分布式锁实战:基于Zookeeper的实现

    1. 创建一个永久节点作为锁节点(/lock2)

    2. 试图加锁的客户端在指定锁名称节点(/lock2)下,创建临时顺序子节点

    3. 获取锁节点(/lock2)下所有子节点

    4. 对所获取的子节点按节点自增序号从小到大排序

    5. 判断自己是不是第一个子节点,若是,则获取锁

    6. 若不是,则监听比该节点小的那个节点的删除事件(这种只监听前一个节点的方式避免了惊群效应)

    7. 若是阻塞申请锁,则申请锁的操作可增加阻塞等待

    8. 若监听事件生效(说明前节点释放了,可以尝试去获取锁),则回到第3步重新进行判断,直到获取到锁

    9. 解锁时,将第一个子节点删除释放

    3. ZK分布式锁的能力

    可能读者是单篇阅读,这里引入上一篇《分布式锁上-初探》中的一些内容,一个分布式锁应具备这样一些功能特点:

    • 互斥性:在同一时刻,只有一个客户端能持有锁

    • 安全性:避免死锁,如果某个客户端获得锁之后处理时间超过最大约定时间,或者持锁期间发生了故障导致无法主动释放锁,其持有的锁也能够被其他机制正确释放,并保证后续其它客户端也能加锁,整个处理流程继续正常执行

    • 可用性:也被称作容错性,分布式锁需要有高可用能力,避免单点故障,当提供锁的服务节点故障(宕机)时不影响服务运行,这里有两种模式:一种是分布式锁服务自身具备集群模式,遇到故障能自动切换恢复工作;另一种是客户端向多个独立的锁服务发起请求,当某个锁服务故障时仍然可以从其他锁服务读取到锁信息(Redlock)

    • 可重入性:对同一个锁,加锁和解锁必须是同一个线程,即不能把其他线程程持有的锁给释放了

    • 高效灵活:加锁、解锁的速度要快;支持阻塞和非阻塞;支持公平锁和非公平锁

    基于上文的内容,这里简单总结一下ZK的能力矩阵(其它分布式锁的情况会在后续文章中补充):

    分布式锁实战:基于Zookeeper的实现

    关于性能不太高的一种说法

    4. InterProcessMutex 使用示例

    Zookeeper 客户端框架 Curator 提供的 InterProcessMutex 是分布式锁的一种实现,acquire 方法阻塞|非阻塞获取锁,release 方法释放锁,另外还提供了可撤销、可重入功能。
    4.1 接口介绍
    4.2 pom依赖
    4.3 示例

    5. DIY一个阉割版的分布式锁

    通过这个实例对照第2节内容来理解加解锁的流程,以及如何避免惊群效应。

  • 0
  • 0
  • 0
  • 19
  • 请登录之后再进行评论

    登录
  • 任务
  • 实时动态
  • 发布
  • 单栏布局 侧栏位置: