Zookeeper(七)分布式锁

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

获取锁实现思路:

1.     首先创建一个作为锁目录(znode),通常用它来描述锁定的实体,称为:/lock_node

2.     希望获得锁的客户端在锁目录下创建znode,作为锁/lock_node的子节点,并且节点类型为有序临时节点(EPHEMERAL_SEQUENTIAL);

        例如:有两个客户端创建znode,分别为/lock_node/lock-1和/lock_node/lock-2

3.     当前客户端调用getChildren(/lock_node)得到锁目录所有子节点,不设置watch,接着获取小于自己(步骤2创建)的兄弟节点

4.     步骤3中获取小于自己的节点不存在 && 最小节点与步骤2中创建的相同,说明当前客户端顺序号最小,获得锁,结束。

5.     客户端监视(watch)相对自己次小的有序临时节点状态

6.     如果监视的次小节点状态发生变化,则跳转到步骤3,继续后续操作,直到退出锁竞争。

 public synchronized boolean lock() throws KeeperException, InterruptedException {
        if (isClosed()) {
            return false;
        }
        // 如果锁目录不存在, 创建锁目录   节点类型为永久类型
        ensurePathExists(dir);

        // 创建锁节点,节点类型EPHEMERAL_SEQUENTIAL 
        // 如果不存在小于自己的节点   并且最小节点 与当前创建的节点相同  获得锁
        // 未获得成功,对当前次小节点设置watch
        return (Boolean) retryOperation(zop);
    }

创建锁目录

    protected void ensurePathExists(String path) {
        ensureExists(path, null, acl, CreateMode.PERSISTENT);
    }
    protected void ensureExists(final String path, final byte[] data,
            final List<ACL> acl, final CreateMode flags) {
        try {
            retryOperation(new ZooKeeperOperation() {
                public boolean execute() throws KeeperException, InterruptedException {
                	// 创建锁目录
                    Stat stat = zookeeper.exists(path, false);
                    // 节点如果存在  直接返回
                    if (stat != null) {
                        return true;
                    }
                    // 创建节点
                    // data为null
                    // flags为持久化节点
                    zookeeper.create(path, data, acl, flags);
                    return true;
                }
            });
        } catch (KeeperException e) {
            LOG.warn("Caught: " + e, e);
        } catch (InterruptedException e) {
            LOG.warn("Caught: " + e, e);
        }
    }

创建锁节点,获得锁目录下的所有节点, 如果为最小节点 获得锁成功

        /**
         * the command that is run and retried for actually 
         * obtaining the lock
         * @return if the command was successful or not
         */
        public boolean execute() throws KeeperException, InterruptedException {
            do {
                if (id == null) {
                    long sessionId = zookeeper.getSessionId();
                    String prefix = "x-" + sessionId + "-";
                    // lets try look up the current ID if we failed 
                    // in the middle of creating the znode
                    findPrefixInChildren(prefix, zookeeper, dir);
                    idName = new ZNodeName(id);
                }
                if (id != null) {
                    List<String> names = zookeeper.getChildren(dir, false);
                    if (names.isEmpty()) {
                        LOG.warn("No children in: " + dir + " when we've just " +
                        "created one! Lets recreate it...");
                        // lets force the recreation of the id
                        id = null;
                    } else {
                        // lets sort them explicitly (though they do seem to come back in order ususally :)
                        SortedSet<ZNodeName> sortedNames = new TreeSet<ZNodeName>();
                        for (String name : names) {
                            sortedNames.add(new ZNodeName(dir + "/" + name));
                        }
                        // 获得最小节点
                        ownerId = sortedNames.first().getName();
                        // lock_1, lock_2, lock_3  传入参数lock_2  返回lock_1
                        SortedSet<ZNodeName> lessThanMe = sortedNames.headSet(idName);
                        if (!lessThanMe.isEmpty()) {
                            ZNodeName lastChildName = lessThanMe.last();
                            lastChildId = lastChildName.getName();
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("watching less than me node: " + lastChildId);
                            }
                            // 次小节点设置watch 
                            Stat stat = zookeeper.exists(lastChildId, new LockWatcher());
                            if (stat != null) {
                                return Boolean.FALSE;
                            } else {
                                LOG.warn("Could not find the" +
                                		" stats for less than me: " + lastChildName.getName());
                            }
                        } else {
                        	// 锁目录下的最小节点  与当前客户端创建相同
                            if (isOwner()) {
                                if (callback != null) {
                                    callback.lockAcquired();
                                }
                                // 获得锁
                                return Boolean.TRUE;
                            }
                        }
                    }
                }
            }
            while (id == null);
            return Boolean.FALSE;
        }
    };

private void findPrefixInChildren(String prefix, ZooKeeper zookeeper, String dir) 
            throws KeeperException, InterruptedException {
        	// 获取锁目录下的所有子节点
            List<String> names = zookeeper.getChildren(dir, false);
            for (String name : names) {
            	//x-sessionId-
                if (name.startsWith(prefix)) {
                    id = name;
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Found id created last time: " + id);
                    }
                    break;
                }
            }
            // 当前锁目录下   没有与当前会话对应的子节点    创建子节点  节点类型为临时顺序节点
            if (id == null) {
            	// dir/x-sessionId-i
                id = zookeeper.create(dir + "/" + prefix, data, 
                        getAcl(), EPHEMERAL_SEQUENTIAL);

                if (LOG.isDebugEnabled()) {
                    LOG.debug("Created id: " + id);
                }
            }

释放锁:

释放锁非常简单,删除步骤1中创建的有序临时节点。另外,如果客户端进程死亡或连接失效,对应的节点也会被删除。

 public synchronized void unlock() throws RuntimeException {
        
        if (!isClosed() && id != null) {
            // we don't need to retry this operation in the case of failure
            // as ZK will remove ephemeral files and we don't wanna hang
            // this process when closing if we cannot reconnect to ZK
            try {
                
                ZooKeeperOperation zopdel = new ZooKeeperOperation() {
                    public boolean execute() throws KeeperException,
                        InterruptedException {
                    	// 删除节点  忽略版本
                        zookeeper.delete(id, -1);   
                        return Boolean.TRUE;
                    }
                };
                zopdel.execute();
            } catch (InterruptedException e) {
                LOG.warn("Caught: " + e, e);
                //set that we have been interrupted.
               Thread.currentThread().interrupt();
            } catch (KeeperException.NoNodeException e) {
                // do nothing
            } catch (KeeperException e) {
                LOG.warn("Caught: " + e, e);
                throw (RuntimeException) new RuntimeException(e.getMessage()).
                    initCause(e);
            }
            finally {
                if (callback != null) {
                    callback.lockReleased();
                }
                id = null;
            }
        }
    }

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

相关推荐

基于ZooKeeper的分布式锁实现(C++版本)

一、简介分布式同步是Zookeeper的功能之一,但Zookeeper的分布式同步(分布式锁)功能并非以直接的接口呈现的。开发者需要额外地基于Zookeeper的节点(node)的分布式同步特性来实现分布式锁的接口。本文将提供基于基于ZooKeeper的分布式锁的C++接口及实现,实现中用到了部分C++11特性。另外,本实现使用的是经过封装的ZooKeeper接口,本文只列出这些ZooKeeper...

warden007的博客 3772

zookeeper实现分布式锁

介绍了Zookeeper如何实现分布式锁,并使用代码进行了演示

凉茶铺的博客 6972

四足机器人通用运动控制策略:强化学习与PD参数优化

运动控制是机器人实现稳定行走和复杂动作的核心技术,其关键在于精确调节关节的刚度和阻尼特性。PD控制器作为基础控制单元,通过比例(P)和微分(D)增益参数直接影响系统响应速度与稳定性。在四足机器人领域,强化学习(RL)通过模拟环境自主学习,能够有效解决传统控制方法难以适应不同形态机器人的痛点。该技术通过非对称Actor-Critic架构,结合状态估计网络和自适应参数采样策略,实现了跨平台的通用运动控制。典型应用包括工业检测、灾害救援等需要高适应性移动能力的场景,其中PD增益优化和形态参数自适应采样成为提升硬件

weixin_30307921的博客 300

基于Zookeeper实现分布式锁

在Zookeeper中的指定路径下创建创建节点,然后客户端根据当前路径下的节点状态来判断是否加锁成功,如下图一种情况为例,线程1创建节点成功后,线程2再去创建节点就会创建失败。(3)如果加锁次数等于0,则释放锁,删除掉创建的临时节点,下一个监听这个节点的客户端会感知到节点删除事件,从而重新去获取锁。3:判断自己的序号是否最小,如果最小的话,代表加锁成功,如果不是最小的话,就对前一个节点创建监听器。2:使用顺序节点的好处是,可以利用锁释放的事件监听机制,来实现。2:第二步客户端拿到加锁路径下所有创建的节点。

weixin_45125989的博客 2915

Android keymint(keymaster)一RKP

Android RKP

weixin_47139576的博客 1万+

飞牛NAS挂载115网盘避坑指南:为什么你的大文件总是传输失败?

本文深入解析了在飞牛NAS上通过AList挂载115网盘时,大文件传输失败的深层原因,包括风控机制、网络协议及兼容性问题。文章提供了从基础排查到高阶优化的系统性解决方案,并建议采用Kopia分片备份等终极策略,以实现稳定可靠的云端数据流转。

weixin_29306011的博客 1690

Zookeeper分布式锁

多个线程去create一个path的时候,只有一个线程可以create成功,也就相当于抢到了锁,其他线程只能不停的尝试create,而抢到锁的线程A,在执行完后释放锁,即delete path,就会有下一个线程create成功。为了避免出现,抢到锁后客户端宕机,导致锁无法释放,即拿锁线程不会delete path,create的节点设置为临时节点,这样当客户端宕机时,节点也跟着自动销毁,也就解锁了。即:只监听想监听到的状态。zk: 临时节点序列化,监听上一个小的节点,实现排队阻塞,实现公平锁。

范大的博客 2278

告别手绘!用Aseprite+Unity Tilemap,从AI生成到2D游戏地图的保姆级搭建流程

本文详细介绍了如何利用Aseprite和Unity Tilemap从AI生成素材到搭建2D游戏地图的完整流程。涵盖AI生成素材的预处理、图层管理、动画制作,以及Unity中的Tilemap系统配置和性能优化技巧,帮助开发者高效创建像素风游戏地图。

weixin_29015483的博客 583

Zookeeper 分布式锁、队列

Zookeeper 分布式锁

杨宇昌的博客 3061

NV 英伟达2022数字芯片笔试题

作者:数字IC打工人 链接:【开卷】第27期 NV 英伟达2022数字芯片笔试题_笔经面经_牛客网 来源:牛客网 1、Single Choice: Given thefollowing FIFO and rules, how deep does the FIFO need to be to preventunderflow or overflow? RULES: clk_A=25MHz; clk_B=100MHz; en_B is periodically asserted: period.

weixin_44072819的博客 6388

第三章-python基础语法

有C语言基础应该这样学 Python。

qq_46187594的博客 1176

zookeeper学习(七)基于zookeeper实现分布式锁

一、分布式锁介绍        分布式锁主要用于在分布式环境中保护跨进程、跨主机、跨网络的共享资源实现互斥访问,以达到保证数据的一致性。二、架构介绍        在介绍使用Zookeeper实现分布式锁之前,首先看当前的系统架构图                        解释: 左边的整个区域表示一个Zookeeper集群,locker是Zookeeper的一个持久节点,node_1、no...

千年似流水的博客 420

拉曼光谱入门:7.拉曼光谱仪光学系统结构详解

本文系统拆解了拉曼光谱仪从激光器输出经聚焦照明、二向色镜/陷波滤光片组滤除瑞丽散射、衍射光栅色散至CCD探测的完整光路,阐述了各光学模块在微弱非弹性散射信号提取、杂散光抑制及高分辨光谱成像中的工程原理与技术参数要求。

qq_53529450的博客 223

zookeeper使用(七)---分布式锁

一、分布式锁 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。如果不同的系统或是同个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要通过一些互斥手段来防止彼此之间的干扰,以保证一致性,在这种情况下,就需要使用分布式锁了。 在平时的实际项目开发中,我们往往很少会去在意分布式锁,而是依赖于关系型数据库固有的排他性来实现不同进程之间的互斥。这确实是一种非常简便且被广泛使用的分布式锁实现方式。然而有一个不争的事实是,目前绝大多数大型分布式系统的性能瓶颈都集中在数据库操作上。因此,如果

wangdamingll的博客 362

【C语言笔记初级篇】第一章:C语言快速入门及注意事项

(1)第一个C语言程序 A:利用vs2010写C语言程序 1:按以下步骤新建工程 2:添加源文件,“.c”文件 B:第一个C语言代码 1:以下是基本的C语言程序 2:由于没有设置连接器,所以打印结果没有显示,按照如下步骤链接控制台 (2)数据类型 A:基本数据类型及占用字节 B:一些概念的梳理 概念一:关于计算机的单位 位(bit):计算机通过电路的开关和闭合处理信息,电路通...

快乐江湖的博客 3737

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

zookeeper分布式锁(七)

zookeeper分布式锁(六)针对创建节点的非“幂等”性操作提供了解决方案,下面,为了避免“羊群效应”,可以用以下的解决方案 execute()方法是前边介绍过的ZookeeperOperation类中的执行方法,在某一个进程申请“锁”的时候会执行这个方法,这个方法 返回“boolean”,用来判断申请成功或者失败,方法访问权限是“public”,没有参数。 方法首先判断当

裴珏的专栏 568

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

ZooKeeper(七)-- ZK原生API实现分布式锁

一、使用场景在分布式应用,往往存在多个进程提供同一服务。这些进程有可能在相同的机器上,也有可能分布在不同的机器上。 如果这些进程共享了一些资源,可能就需要分布式锁来锁定对这些资源的访问。...

u010821757的博客 252

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Zookeeper笔记⑦——分布式锁和分布式配置中心

分布式锁 临时顺序节点 监听前一个节点 分布式配置中心

ww0peo的博客 163

ZooKeeper完全解析(七) 使用ZooKeeper实现分布式锁之Java实现

  在上一节中,我们讲了使用ZooKeeper来实现分布式锁的原理,链接为  ZooKeeper完全解析(六) 使用ZooKeeper实现分布式锁之实现原理 ,这一节我们来讲一下如何使用Java来实现分布式锁:   在实现原理中,我们把使用ZooKeeper实现分布式锁分成了3步,在Java实现中,我们将第1步写成一个方法,第2、3步写成一个方法:   第一步: public vo...

HappyHeng的博客 547

七张图彻底讲清楚ZooKeeper分布式锁的实现原理【石杉的架构笔记】

七张图彻底讲清楚ZooKeeper分布式锁的实现原理【石杉的架构笔记】 欢迎关注个人公众号:石杉的架构笔记(ID:shishan100) 周一至周五早8点半!精品技术文章准时送上! 一、写在前面 之前写过一篇文章(《拜托,面试请不要再问我Redis分布式锁的实现原理》),给大家说了一下Redisson这个开源框架是如何实现Redis分布式锁原理的,这篇文章再给大家聊一下ZooKeeper实现分布式...

mhHao的博客 449

分布式学习笔记七:基于zookeeper实现分布式锁

一、分布式锁介绍         分布式锁主要用于在分布式环境中保护跨进程、跨主机、跨网络的共享资源实现互斥访问,以达到保证数据的一致性。 二、架构介绍         在介绍使用Zookeeper实现分布式锁之前,首先看当前的系统架构图         解释: 左边的整个区域表示一个Zookeeper集群,locker是Zookeeper的一个持久节点,node_1、node_2、n...

畅志聪的专栏 181

图解curator如何实现zookeeper分布式锁

curator提供的四种分布式锁概述(InterProcessMutex、InterProcessSemaphoreMutex、InterProcessReadWriteLock、InterProcessMultiLock),Zookeeper分布式锁实现思路,Zookeeper分布式锁解决的问题,Zookeeper分布式锁优缺点,InterProcessMutex实现zookeeper分布式原理/源码解析,图解curator解锁 / 解锁流程

健身变秃,coding变强 1万+

ZooKeeper实现分布式锁

一、Zookeeper实现分布式锁思路 1.1.分布式锁应具备哪些条件 分布式锁应该具备以下条件: 在分布式环境下,在一个时间点,最多被一个请求方持有 高可用、高性能的获取和释放 具备可重入性 具备失效机制,防止死锁 具备非阻塞特性,即没有获取到锁将直接返回失败 1.2.ZooKeeper实现分布式锁所具备的特性 1.2.1.高可用、高性能 ZooKeeper的数据是内存读取的,本身就具备高性能特性 ZooKeeper具备很好的故障恢复能力 在集群模式下,当Leader节点宕机后,当前集群会选出新的

qq_28136919的博客 4815
上一篇: Zookeeper(六)数据模型
下一篇: Redis复制与可扩展集群搭建
胸口碎大石_
博客等级 码龄17年 1154粉丝 82原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值