排他锁(X)

这里主要讲讲分布式锁中的排他锁。排他锁(Exclusive Locks,简称X锁),又称为写锁或独占锁,是一种基本的锁类型。如果事务T1对数据对象O1加上了排他锁,那么在整个加锁期间,只允许T1对O1进行数据的读取和更新操作,其它任何事务都不能对O1进行任何类型的操作,直道T1释放了排他锁。

定义锁

在ZooKeeper中,可以通过在ZooKeeper中创建一个数据节点来表示一个锁。比如,/exclusive_lock/lock节点(znode)就可以表示为一个锁。

获取锁

在需要获取排他锁时,所有的客户端都会试图通过create()接口,在/exclusive_lock节点下创建临时的子节点/exclusive_lock/lock,但ZooKeeper的强一致性最终只会保证仅有一个客户单能创建成功,那么就认为该客户端获取了锁。同时,所有没有获取锁的客户端事务只能处于等待状态,这些处于等待状态的客户端事先可以在/exclusive_lock节点上注册一个子节点变更的Watcher监听,以便实时监听到子节点的变更情况。

释放锁

在“定义锁”部分,我们已经提到/exclusive_lock/lock是一个临时节点,因此在以下两种情况下可能释放锁。

  • 当前获取锁的客户端发生宕机,那么ZooKeeper服务器上保存的临时性节点就会被删除;
  • 正常执行完业务逻辑后,由客户端主动来将自己创建的临时节点删除。

无论什么情况下,临时节点/exclusive_lock/lock被移除,ZooKeeper都会通知在/exclusive_lock注册了子节点变更Watcher监听的客户端。这些客户端在接收到通知以后就会再次发起获取锁的操作,即重复“获取锁”过程。排他锁流程如下:

下面的代码(java)演示了使用Curator框架来实现ZooKeeper分布式锁

import java.util.concurrent.TimeUnit;
import lombok.Cleanup;
import lombok.SneakyThrows;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat; public class ZkLock { @SneakyThrows
public static void main(String[] args) { final String connectString = "localhost:2181,localhost:2182,localhost:2183"; // 重试策略,初始化每次重试之间需要等待的时间,基准等待时间为1秒。
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); // 使用默认的会话时间(60秒)和连接超时时间(15秒)来创建 Zookeeper 客户端
@Cleanup CuratorFramework client = CuratorFrameworkFactory.builder().
connectString(connectString).
connectionTimeoutMs(15 * 1000).
sessionTimeoutMs(60 * 100).
retryPolicy(retryPolicy).
build(); // 启动客户端
client.start(); final String lockNode = "/lock_node";
InterProcessMutex lock = new InterProcessMutex(client, lockNode);
try {
// 1. Acquire the mutex - blocking until it's available.
lock.acquire(); // OR // 2. Acquire the mutex - blocks until it's available or the given time expires.
if (lock.acquire(60, TimeUnit.MINUTES)) {
Stat stat = client.checkExists().forPath(lockNode);
if (null != stat){
// Dot the transaction
}
}
} finally {
if (lock.isAcquiredInThisProcess()) {
lock.release();
}
}
} }

maven引用

<!--curator这个开源项目提供zookeeper分布式锁实现-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>

Curator框架实现ZooKeeper分布式锁的更多相关文章

  1. Curator实现zookeeper分布式锁的基本原理

    一.写在前面 之前写过一篇文章(<拜托,面试请不要再问我Redis分布式锁的实现原理>),给大家说了一下Redisson这个开源框架是如何实现Redis分布式锁原理的,这篇文章再给大家聊一 ...

  2. 女朋友也能看懂的Zookeeper分布式锁原理

      前言 关于分布式锁,在互联网行业的使用场景还是比较多的,比如电商的库存扣减,秒杀活动,集群定时任务执行等需要进程互斥的场景.而实现分布式锁的手段也很多,大家比较常见的就是redis跟zookeep ...

  3. ZooKeeper分布式锁的实现原理

    七张图彻底讲清楚ZooKeeper分布式锁的实现原理[石杉的架构笔记] 文章转载自:https://juejin.im/post/5c01532ef265da61362232ed#comment(写的 ...

  4. ZooKeeper 分布式锁 Curator 源码 03:可重入锁并发加锁

    前言 在了解了加锁和锁重入之后,最需要了解的还是在分布式场景下或者多线程并发加锁是如何处理的? 并发加锁 先来看结果,在多线程对 /locks/lock_01 加锁时,是在后面又创建了新的临时节点. ...

  5. Zookeeper分布式锁实现Curator十一问

    前面我们剖析了Redisson的源码,主要分析了Redisson实现Redis分布式锁的15问,理清了Redisson是如何实现的分布式锁和一些其它的特性.这篇文章就来接着剖析Zookeeper分布式 ...

  6. Curator Zookeeper分布式锁

    Curator Zookeeper分布式锁 pom.xml中添加如下配置 <!-- https://mvnrepository.com/artifact/org.apache.curator/c ...

  7. ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放

    ZooKeeper 分布式锁 Curator 源码 02:可重入锁重复加锁和锁释放 前言 加锁逻辑已经介绍完毕,那当一个线程重复加锁是如何处理的呢? 锁重入 在上一小节中,可以看到加锁的过程,再回头看 ...

  8. ZooKeeper 分布式锁 Curator 源码 04:分布式信号量和互斥锁

    前言 分布式信号量,之前在 Redisson 中也介绍过,Redisson 的信号量是将计数维护在 Redis 中的,那现在来看一下 Curator 是如何基于 ZooKeeper 实现信号量的. 使 ...

  9. Zookeeper 分布式锁 (图解+秒懂+史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

随机推荐

  1. Python3 解决windows里PIP下载安装速度慢

    直接保存为xxx.py运行即可 自动在用户文件夹创建pip文件夹,并创建配置文件:pip.ini 从此告别pip install XXXX 下载模块速度超级慢的问题! # -*- coding: ut ...

  2. Python 的稀疏矩阵

    什么是稀疏矩阵 简单的说,如果一个矩阵中大部分元素为0,就被称为稀疏矩阵. 对于稀疏矩阵而言,实际存储的数据项很少.如果在计算机中采用传统的二维数组(Python中用二维列表)来存储稀疏矩阵,就会浪费 ...

  3. C/ C++ 快速上手

    C++ 快速上手 (一)https://www.cnblogs.com/cosmo89929/archive/2012/12/22/2828745.html C++ 快速上手 (二)https://w ...

  4. redis-存储命令

    一.String类型: 1.赋值/取值 set key valueget key 2.设置/获取多个键值   mset key1 value1 key2 value2 …   mget key1 ke ...

  5. Centos 7 中的ulimit -n 65535 对进程的文件句柄限制不生效??

    今日闲来无事,就看群里大佬吹牛逼了,偶然一条技术疑问提出来了,神奇啊,作为广大老司机技术交流群体竟然还有这么深入的研究? 大佬问:这个文件句柄限制怎么设置了/etc/security/limits.c ...

  6. Django的orm操作之表查询二

    复习 单表查询 # 单表操作 # 增 # 方式1 user_obj=models.User.objects.create(**kwargs) # 之一create # 方式2 user_obj=mod ...

  7. Mirai 通过弱密码爆破摄像头 形成僵尸网络——尼玛值得深思的是作者居然是做安全研究的

    Mirai(日语:ミライ[1],中文直译“未来”[2][3])是一款恶意软件,它可以使运行Linux的计算系统成为被远程操控的“僵尸”,以达到通过僵尸网络进行大规模网络攻击的目的.Mirai的主要感染 ...

  8. 2019年杭电多校第二场 1002题Beauty Of Unimodal Sequence(LIS+单调栈)

    题目链接 传送门 思路 首先我们对\(a\)正反各跑一边\(LIS\),记录每个位置在前一半的\(LIS\)中应该放的位置\(ans1[i]\),后一半的位置\(ans2[i]\). 对于字典序最小的 ...

  9. 31、Python程序中的协程操作(greenlet\gevent模块)

    一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 对比操作系统控制线程的切换,用 ...

  10. ios app ipv6 审核总结

    AAAA记录(AAAA record)是用来将域名解析到IPv6地址的DNS记录.用户可以将一个域名解析到IPv6地址上,也可以将子域名解析到IPv6地址上. 1)$ dig +nocmd +nost ...