排他锁(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. 一招解决------VMware虚拟机 Centos7网络配置 ping:www.baidu.com:未知的名称或服务 ping不通

    一招解决------VMware虚拟机 Centos7网络配置 ping:www.baidu.com:未知的名称或服务 ping不通 1.首先点击VMware的编辑,再点击虚拟网路编辑器. 2.进入虚 ...

  2. Django 之瀑布流实现

    需求分析 现在是 "图片为王"的时代,在浏览一些网站时,经常会看到类似于这种满屏都是图片.图片大小不一,却按空间排列,就这是瀑布流布局. 以瀑布流形式布局,从数据库中取出图片 每次 ...

  3. Vmware克隆Centos6.5虚拟机网卡无法启动问题

    1.编辑eth0的配置文件:vi /etc/sysconfig/network-scripts/ifcfg-eth0,删除HWADDR地址那一行及UUID的行如下: #HWADDR=:0c::::9f ...

  4. The 2019 Asia Yinchuan First Round Online Programming F. Moving On

    t题目链接:https://nanti.jisuanke.com/t/41290 思路:题目意思很容易想到floyd,但是由于危险度的限制,我们该怎么跑floyd呢. 一开始理解错题目了,以为u-&g ...

  5. 2019年牛客多校第二场 F题Partition problem 爆搜

    题目链接 传送门 题意 总共有\(2n\)个人,任意两个人之间会有一个竞争值\(w_{ij}\),现在要你将其平分成两堆,使得\(\sum\limits_{i=1,i\in\mathbb{A}}^{n ...

  6. python 验证码识别示例(四) 简单验证码识别

    今天介绍一个简单验证的识别. 主要是标准的格式,没有扭曲和变现.就用 pytesseract 去识别一下. 验证码地址:http://wsxf.mca.gov.cn/zfp/Random.cmd?d= ...

  7. ROS 的一些常用命令行功能

    1.安装并添加源sudo gedit /etc/apt/sources.list更新下sudo apt-get update添加 sources.list,如sudo sh -c '. /etc/ls ...

  8. beforeRouteEnter 与 beforeRouteUpdate(watch $route 对象) 的区别

    项目 区别 适用场景 网址 beforeRouteEnter beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建.不过,你可以通过 ...

  9. python 连接 redis cluster 集群

    一. redis集群模式有多种, cluster模式只是其中的一种实现方式, 其原理请自行谷歌或者百度, 这里只举例如何使用Python操作 redis cluster 集群 二. python 连接 ...

  10. hive的常用函数工作总结

    1.concat_ws 它是一个特殊形式的 CONCAT() concat_ws(分隔符,参数1,参数2.......) as 字段 2.split 返回值为一个数组 a.基本用法: 例1:split ...