zookeeper 分布式锁之比较基础的原理

Zookeeper实现分布式锁 如何用Zookeeper实现分布式锁? 在学习分布式锁之前,需要首先了解一下Zookeeper的[临时顺序节点]。 什么是临时顺序节点? 让我们来回顾一下Zookeeper节点的概念: Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Znode。 Znode分为四种类型: 1.持久节点 (PERSISTENT) 默认的节点类型。创建节点的客户端与zook... 阅读详情

为什么需要分布式锁?

如下图所示 ,当nignx 并发量到达10w ,tomcat1,tomcat2,tomcat3 都是订单服务,在如此高的并发量下面, 如果不做分布式锁,那么后台生成的订单编号必定重复。如果不是分布式的话,那么只要加锁就行, 可是分布式的话,不是同一个jvm那么 加sync 锁也是不行的.

那么我们如何去解决呢?看下图

一、通过临时文件建立分布式锁

当这三个tomcat 去创建订单的时候先去zookeeper 的某个文件夹下加把锁(创建个文件),当某个tomcat 申请锁成功后(创建某个文件成功) ,另外两个tomcat 就等待(同一个目录下不能创建同样名字的文件)。

我用个类比的方法说一遍。 比如这三个tomcat 生成订单号的时候, 都要去/lock目录下生成createOrderId 这个名字的文件夹,当tomcat2 创建文件夹成功了,tomcat1,和tomcat2 就不能创建createOrderId这个名字的文件夹了,因为相同目录下文件夹的名字不能重复。这样创建不了文件夹的就当做没有获取到锁。当创建成功文件夹的时候。我们通过get 文件名的命令可以回去到很多信息有一个就是sessionid ,根据session 可以判断是和创建文件的客户端断开连接了,如果断开则销毁临时文件(下图中ephemeralOwner 即临时文件所有者就是sessionid)。这样我们可以通过关闭客户端来释放锁。

 

 1)加锁

lock()是获取锁的方法,先是试着获取锁trylock()如果成功打印信息,否则等待着释放锁再去获取锁

 @Override
    public void lock() {
        if(tryLock()) {
            logger.info(Thread.currentThread().getName() + "-->获取锁成功");
        } else {
            waitforlock();
            lock();
        }
    }

    protected abstract boolean tryLock();

    protected abstract void waitforlock();

    /**
        释放锁
     */
    @Override
    public void unlock() {
        client.close();
    }

 2)创建临时文件,注册监听事件

client.createEphemeral(path);就是去创建临时节点成功就返回true,否者获取锁失败waitforlock()就是监听需要创建的文件夹,

向client 注册监听事件.如果当前路劲是存在的,则阻塞在这边。当文件状态是删除的,触发监听事件,所有的countDownLauch全部放行。并且这时候取消监听事件 waitforlock()的方法全部走完,再走上图代码段中的else 里面的lock()方法继续去竞争锁

public class ZkLockImpl extends ZkAbstractLock {

    private CountDownLatch cdl = null;

    /**
     * 这个就是去创建znode,如果能成功就返回true
     */
    @Override
    protected boolean tryLock() {
        try {
            client.createEphemeral(path);
            return true;
        } catch (ZkException e) {
            return false;
        }
    }

    /**
     * waitforlock要监控前面的那个线程的/lock节点
     * 要知道/lock节点有没有删除
     */
    @Override
    protected void waitforlock() {

        IZkDataListener iZkDataListener = new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {

            }

            @Override
            public void handleDataDeleted(String dataPath) throws Exception {
                if (cdl != null) {
                    cdl.countDown();
                }
            }
        };

        //这里注册path的事件
        client.subscribeDataChanges(path, iZkDataListener);

        if (client.exists(path)) {
            cdl = new CountDownLatch(1);
            try {
                //这里是要等待,只有当前面的线程释放了锁,也就是说前面的线程的zookeeper会话失效以后
                //才不需要等待
                cdl.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        client.unsubscribeDataChanges(path, iZkDataListener);
    }
}

下面是 运用发射枪(countDownLauch)模拟101 个并发

public class OrderService implements Runnable {

    Logger logger  = LoggerFactory.getLogger(getClass());

    private OrderNumFactory onf = new OrderNumFactory();

    private static Integer count = 101;

    private static CountDownLatch cdl = new CountDownLatch(count);

    private Lock lock = new ZkImproveLockImpl();

    @Override
    public void run() {
        try {
            cdl.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        createOrderNum();
    }

    public void createOrderNum() {
        lock.lock();
        String orderNum = onf.createOrderNum();
        logger.info(Thread.currentThread().getName()+ "创建了订单号:[" + orderNum + "]!");
        lock.unlock();
    }

    public static void main(String[] args) {
        for (int i = 0; i < count; i++) {
            new Thread(new OrderService()).start();
            cdl.countDown();
        }
    }
}

二、利用临时顺序文件来创建分布式锁

先在实现类中创建一个永久文件以及三个变量

private String currentPath;

    private String beforePath;

    private CountDownLatch cdl;

    public ZkImproveLockImpl() {
        if(!this.client.exists(path)) {
            this.client.createPersistent(path,"xx");
        }
    }

代码逻辑

当trylock 的时候看看此类的当前路径(currentPath)存在不存在。 如果不存在,就在这个永久节点下创建一个临时顺序节点,若存在,再去判断这个永久节点下第一个顺序节点是不是自己,如果是则获取锁,执行业务,最终关掉客户端 当客户端关闭,临时文件也会消失。 如果不是则获取当前文件(currentPath)的前面一个文件, 并且去监听这个文件,当他被删除的时候,解开countDownLatch 再去获取锁 执行业务,关闭连接,取消监听。

@Override
    protected boolean tryLock() {

        if(currentPath == null || currentPath.length() <= 0) {
            currentPath = this.client.createEphemeralSequential(path + "/","aa");
        }

        List<String> childrens = this.client.getChildren(path);
        Collections.sort(childrens);


        //这个就是判断当前用户创建的临时节点的名称是否跟孩子里面最新的那个相等,如果相等就代表可以获得锁
        if(currentPath.equals(path + "/" + childrens.get(0))) {
            return true;
        } else {
            //如果不能获取到这把锁,那么必须要获取到前面那个节点,要注册对前面那个节点的事件监控

            System.out.println(currentPath.substring(5));
            int i = Collections.binarySearch(childrens,currentPath.substring(6));
            System.out.println(i);

            beforePath = path + "/" + childrens.get(i - 1);

        }


        return false;
    }

    @Override
    protected void waitforlock() {
        IZkDataListener iZkDataListener = new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {

            }
            @Override
            public void handleDataDeleted(String dataPath) throws Exception {
                if(cdl != null) {
                    cdl.countDown();
                }
            }
        };

        client.subscribeDataChanges(beforePath,iZkDataListener);

        if(client.exists(beforePath)) {
            cdl = new CountDownLatch(1);

            try {
                cdl.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        client.unsubscribeDataChanges(beforePath,iZkDataListener);
    }

当然apache里面有netflix 贡献出来的curator项目将这些复杂的部分封装起来了,但是原理我们还是要好好看看的。

springboot基于zookeeper实现分布式锁 参考链接: https://blog.youkuaiyun.com/wuzhiwei549/article/details/80692278 https://blog.52itstyle.vip/archives/3202/ 先说明一下zookeeper实现分布式锁的原理,这里参看csdn一篇非常好的文章,如果不想看原理直接跳过看后面的具体代码实现 单机应用架构中,秒杀案例使用ReentrantLcok或者s... 阅读详情

相关推荐

Zookeeper系列——6Zookeeper的分布式锁及Leader选举原理分析

分布式锁的实现原理;Zookeeper实现分布式锁的核心流程解析;Zookeeper实现Leader选举的核心思想

Eclipse_2019的博客 874

Zookeeper实战——分布式锁实现以及原理

文章目录Zookeeper 分布式锁实现原理具体流程代码实现客户端创建工厂类创建 Lock 锁接口Lock 实现类(ZkLock)自定义 ZK 分布式锁测试独占锁 & 共享锁Curator 实现分布式锁ZooKeeper 分布式锁的优缺点 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。分布式锁的实现方式有很多种,比如 Redis 、数据库 、zookeeper 等。这篇文章主要介绍用 Zookeeper 实现分布式锁。 Zookeeper 分布式锁实现原理 先说结论:Zookeeper.

KIMTOU的博客 1万+

图文并茂:Zookeeper分布式锁原理

而且用临时顺序节点的另外一个用意就是,如果某个客户端创建临时顺序节点之后,不小心自己宕机了也没关系,zk感知到那个客户端宕机,会自动删除对应的临时顺序节点,相当于自动释放锁,或者是自动取消自己的排队。删除了那个节点之后,zk会负责通知监听这个节点的监听器,也就是客户端B之前加的那个监听器,说兄弟,你监听的那个节点被删除了,有人释放了锁。咱们就假设客户端A抢先一步,对zk发起了加分布式锁的请求,这个加锁请求是用到了zk中的一个特殊的概念,叫做“临时顺序节点”。zk里有一把锁,这个锁就是zk上的一个节点。...

m0_67322837的博客 1122

Zookeeper分布式锁的原理

如果客户端创建的节点不是序号最小的,那么它会找到比自己序号小的最大节点,然后对这个节点进行监听。这样,当持有锁的客户端释放锁(也就是其创建的节点被删除)后,原来监听这个节点的客户端就会收到通知,从而尝试获取锁。临时节点的特性保证了,如果持有锁的客户端因为某些原因(如崩溃或网络问题)与 Zookeeper 的连接断开,其创建的节点会被自动删除,从而释放锁。这样,我们就可以避免 "羊群效应",即当锁被释放时,大量的客户端都尝试去获取锁,从而造成大量的网络拥塞。也就是说,请求锁的顺序就是获得锁的顺序。

互联网知识分享 1466

【檀越剑指大厂--zookeeper】zookeeper学习

Zookeeper 是 Apache Hadoop 项目下的一个子项目,是一个树形目录服务。Zookeeper 翻译过来就是 动物园管理员,他是用来管 Hadoop(大象)、Hive(蜜蜂)、Pig(小 猪)的管理员。简称 zkZookeeper 是一个分布式的、开源的分布式应用程序的协调服务。Curator 是 Apache ZooKeeper 的 Java 客户端库。原生 Java APIZkClientCurator。

优快云站内信: https://i.youkuaiyun.com/#/msg/chat/qyj19920704 3万+

Zookeeper分布式锁的概念及原理

基于分布式的场景,JVM锁已经远远无法满足了,这时就需要一种统一配置的锁,那就是分布式锁的组件,让所有的程序副本都连接到这个分布式锁组件,由分布式锁提供一个唯一的锁,比如第一个请求到达APP1节点上了,此时APP1就会去分布式锁中取一个锁,让这个请求线程安心处理数据,当数据处理完成后,再将锁还回去,第二个请求进来如果发现锁已经被APP1使用了,那么就会处于等待的状态,当APP1处理完成后,APP2再拿到锁去处理数据。用于所有客户端创建的子节点间进行比较,如果发现自己的子节点编号比较小,那么就获取锁。

江晓龙的博客 1万+

分布式锁实现方案-基于zookeeper的分布式锁实现(原理与代码)

分布式锁是一种用于控制分布式系统中对共享资源访问的同步机制,它确保在多个节点或进程中访问共享资源时的排他性。分布式锁的应用场景广泛,如防止多个用户同时修改数据、控制分布式系统中对共享资源的并发访问等。分布式锁的实现方式主要有三种,包括: 基于数据库的实现方式。基于缓存(如Redis或Memcached)的实现方式。基于ZooKeeper的实现方式等。在选择和使用分布式锁时,需要考虑到具体的业务需求、性能要求以及系统的可用性和可扩展性。今天我们就来看下如何基于Zookeeper实现分布式锁。

qq_25409421的博客 2842

什么是plm系统?-数字化转型网

当今世界,产品研发能力是企业在激烈的市场竞争中保持战略优势的核心竞争力之一。如何有效地缩短产品研发周期、改善产品服务的设计迭代流程、有效降低产品的研发成本,也是企业面临的主要问题之一。PLM(Product Lifecycle Management,产品生命周期管理)在优化产品研发的全管理流程、增强企业产品的市场竞争力方面具有关键的作用。

cxo17757154043的博客 883

zookeeper实现分布式锁原理

zookeeper实现分布式锁原理

zhenghuishengq的博客 1068

iTerm2+oh-my-zsh最全配置

iTerm2+oh-my-zsh最全配置安装前先看效果图一.安装[iTem2](https://iterm2.com/)二.安装[oh-my-zsh](https://ohmyz.sh/)三.安装[Powerline](https://powerline.readthedocs.io/en/latest/installation.html)四.安装 [Meslo](https://github.com/powerline/fonts) 字体库五.安装agnoster主题六.安装语法高亮七.安装代码补全插件八

xinximo的博客 2611

Cadence Sigrity PowerSI实战:从.brd到S参数提取的完整避坑指南

本文详细介绍了使用Cadence Sigrity PowerSI进行信号完整性分析的完整流程,从.brd文件预处理到S参数提取的关键技巧。通过实战案例和避坑指南,帮助工程师高效解决高速PCB设计中的信号质量问题,提升仿真精度和设计效率。

carrot的博客 694

ZooKeeper 分布式锁详解 —— 从原理、设计到实战优化

ZooKeeper 分布式锁通过临时顺序节点和 Watcher 机制实现了对共享资源的互斥访问。它利用 ZooKeeper 的强一致性、自动删除临时节点和顺序节点特性,使得锁的创建、竞争和释放变得简单而高效。尽管实现过程中需要处理竞态、锁重入和性能瓶颈等问题,但通过合理的设计和工具(如 Curator),可以构建出健壮的分布式锁解决方案,为分布式系统提供可靠的协调机制。

2301_80320652的博客 1473

Latex小白也能搞定!5分钟教你用Overleaf打造个性化简历(附免费模板)

本文为LaTeX新手提供了一份快速上手指南,教你如何在5分钟内使用Overleaf在线平台和现成模板,轻松打造专业且个性化的简历。文章详细介绍了从选择模板、替换个人信息到进行颜色、图标等个性化调整的完整流程,让你无需深入学习LaTeX语法,即可高效制作出排版精美、脱颖而出的求职简历。

2a4s6d8f0g的博客 684

分布式锁的实现原理

一、线程锁、进程锁 在介绍分布式锁之前,我们先来简单介绍下线程锁、进程锁。 线程锁 线程锁,主要用来解决的问题是:保护临界区域。 使用方式:lock(mutex)、unlock(mutex)。 进程锁 为了控制同一操作系统中多个进程访问一个共享资源。 nginx中的accept锁,就是一种进程锁,它采用的实现方式是:共享内存+信号量。 二、分布式锁 2.1 分布式锁的实现方案 分布式锁的常见实现方案有: 1)数据库 redis,mysql 2)zookeeper 高效性比较:zookeeper &.

locahuang的博客 4058

运放电路实战:5分钟搞定加法器与减法器的电路设计与调试(附避坑指南)

本文从实战角度出发,详细讲解了运算放大器加法器与减法器的电路设计与调试方法。针对加法器,重点分析了利用“虚地”特性简化设计和选型要点;对于减法器,则深入剖析了决定精度的核心——电阻匹配问题,并提供了使用电阻网络等提升共模抑制比的实用策略。文章还分享了从仿真到实物焊接的完整流程与常见避坑技巧,帮助电子爱好者快速掌握这两种基础运放电路。

weixin_28323057的博客 468

ITK-snap进行分割区域标注、三维显示及改变显示颜色

在进行医学图像器官分割时,无论我们是用传统方法还是深度学习,最后肯定要用到手动分割的区域作为金标准来验证我们方法的精度。但是手动标注器官的轮廓是十分耗时的,这里我介绍一个比较简单的标注方法,以肺分割作为例子。 我们使用ITK-snap作为分割标注工具。 当切片间距离比较小时,比如1mm,一个患者的完整HRCT序列通常在200张以上,如果让医生一一进行分割区域标注是非常耗时乏味的。因此,我们可以使用最简单的阈值法比如OSTU,加上基本的形态学操作对肺进行粗分割得到粗略的分割掩码,在此基础上再手动的对分割结果进

u010409517的博客 2万+

Zookeeper 分布式锁原理与实现

在分布式系统中,确保多个进程或服务实例在访问共享资源时能够互斥,是保证数据一致性和系统稳定性的关键。一个典型的场景是,当多个服务实例需要同时更新同一份数据时,如果没有适当的机制来控制访问顺序,可能会导致数据冲突或不一致。为了解决这个问题,分布式锁应运而生。接下来,我们将深入探讨Zookeeper在实现分布式锁方面的知识。分布式锁是分布式系统中的一种同步机制,它允许多个进程或服务实例在分布式环境中对共享资源进行互斥访问。

我是Java程序员廖志伟,感谢朋友们的支持!不定期贡献一篇高品质、过万文字、图文并茂且附有视频解说、满载代码示例注释的良心之作,坚决杜绝粗制乱造。 922

【Unity】NGUI下载与导入

Unity3D插件NGUI的下载和导入。

Get your hands dirty 3万+

Zookeeper分布式锁实现

zookeeper最初设计的初衷就是为了保证分布式系统的一致性。本文将讲解如何利用zookeeper的临时顺序结点,实现分布式锁。

2301_76632762的博客 1373

基于STM32的IMU惯性/姿态解算与多参数上位机可视化实现_资料编号38

本项目实现基于STM32F103C8T6标准库,对姿态/惯性(IMU)传感器姿态解算,通过USB-TTL转串口模块将姿态角/欧拉角、加速度、角速度、磁场、气压、海拔高度、磁力计温度、气压计温度等数据显示在PC端上位机,系统采用可充电锂电池供电。

嵌入式阿齐Archie 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

深入解析 ZooKeeper 分布式锁原理

深入解析 ZooKeeper 分布式锁原理 接着上文,我们继续说一下Zookeeper的分布式锁原理,最后简单再说一下脑裂的概念及Zookeeper是如何处理的。 分布式锁 为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度。而这个分布式协调技术的核心就是来实现这个分布式锁。 一、实现原理 在Zookeeper中实现分布式锁有两种方案,一是使用临时节点,二是使用临时有序节点。这两种方式有什么区别?我们又该用哪种呢? 临时节点 临时节点方案的原理如下: 让多个进程(

LeoByte的编程驿站 1922

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Zookeeper 分布式锁原理

在Redis分布式锁一文中, 作者介绍了如何使用Redis开发分布式锁。 Redis分布式锁具有轻量高吞吐量的特点,但是一致性保证较弱。我们可以使用Zookeeper开发分布式锁,来满足对高一致性的要求。 Zookeeper 分布式锁原理 Zookeeper 节点具有一些性质可以帮助我们开发分布式锁: 临时节点: 客户端可以创建临时节点,当客户端会话终止或超时后Zookeeper会自动删除临...

li123128的博客 1575

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Zookeeper原理--分布式锁

其他网址 三种实现分布式锁的方式_vincent-优快云博客_分布式锁、 节点 其他网址 《从Paxos到Zookeeper 分布式一致性原理与实践》=>4.1.3 ZooKeeper的基本概念 让我们来回顾一下Zookeeper节点的概念: Zookeeper的数据存储结构就像一棵树,这棵树由节点组成,这种节点叫做Znode。Znode分为四种类型: 1.持久节点 (PERSISTENT) 默认的节点类型。创建节点的客户端与Zookeeper断开连接...

IT利刃出鞘的博客 3377
上一篇: mongodb 使用
下一篇: Mybatis之SqlSessionFactoryBean源码初步解析(三)mapper的动态代理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值