zookeeper经典应用场景之分布式锁

1. 什么是分布式锁

        在单体的应用开发场景中涉及并发同步的时候,大家往往采用Synchronized(同步)或者其他同一个JVM内Lock机制来解决多线程间的同步问题。在分布式集群工作的开发场景中,就需要一种更加高级的锁机制来处理跨机器的进程之间的数据同步问题,这种跨机器的锁就是分布式锁

2. 分布式锁的主流方案

  1. 基于数据库的分布式锁:这种方案使用数据库的事务和锁机制来实现分布式锁。虽然在某些场景下可以实现简单的分布式锁,但由于数据库操作的性能相对较低,并且可能面临锁表的风险,所以一般不是首选方案。
  2. 基于Redis的分布式锁:Redis分布式锁是一种常见且成熟的方案,适用于高并发、性能要求高且可靠性问题可以通过其他方案弥补的场景。Redis提供了高效的内存存储和原子操作,可以快速获取和释放锁。它在大规模的分布式系统中得到广泛应用。
  3. 基于ZooKeeper的分布式锁:这种方案适用于对高可靠性和一致性要求较高,而并发量不是太高的场景。由于ZooKeeper的选举机制和强一致性保证,它可以处理更复杂的分布式锁场景,但相对于Redis而言,性能可能较低。

2.1 基于数据库实现分布式锁设计思路

        我们可以利用数据库的唯一索引来实现,唯一索引天然具有排他性。设计思路如下图所示:

这种基于数据库的分布式锁会有什么问题呢? 很明显,容易出现死锁的问题。基于数据库设计分布式锁,在当下不是首选方案,不在过多赘述,大家明白其中设计思想即可。

2.2 基于redis实现分布式锁设计思路

        基于redis设计的分布式锁设计是利用了其SETNX的特性,其是set If not exist的简写。意思就是当 key 不存在时,设置 key 的值,存在时,什么都不做。以下是一个基于redis设计分布式锁的一个基础方案

        上述方案,从技术的角度看:setnx 占锁成功,但业务代码出现异常或者服务器宕机,没有执行删除锁的逻辑,就会造成死锁。

        上述是基本方案,之所以称之为基本方案,因为里面还是会有很多问题,比如没有来得及释放锁导致死锁;等待抢锁的线程太多,当当前锁释放后,等待的线程全都去抢占改锁出现的羊群效应;总之值得优化的地方还很多,本文中不在过多赘述,大家体会其中的设计思想,后续会出redis设计分布式锁的详细文章。

2.3 基于zookeeper实现分布式锁

2.3.1 青铜方案

使用临时 znode 来表示获取锁的请求,创建 znode成功的用户拿到锁。

        想一想,上述设计存在什么问题?
        如果所有的锁请求者都 监听 锁持有者,当代表锁持有者的 znode 被删除以后,所有的锁请求者都会通知到,都会竞争同一个资源,但是只有一个锁请求者能拿到锁。这就是羊群效应。 

2.3.2 白银方案

        我们想一下青铜方案的问题,就是羊群效应,那么在并发编程中是如何处理这种羊群效应的呢?并发编程中,当资源被占用时,其他线程都进入阻塞队列,资源被释放后,阻塞队列中的一个线程出队,进行获取资源。同理,我们想一想,如果等待监听的线程在一个队列里面,遵循先进先出的规则,我们就可以实现一把公平分布式锁的实现?

        zookeeper的临时有序znode就是一个天然的队列,我们可以利用这个特性,使用临时有序znode来表示获取锁的请求,线程创建最小后缀数字 znode 的用户成功拿到锁。设计思路如下:

2.3.1 zookeeper之Curator 可重入分布式锁

        上述我们讨论了一些利用zookeeper节点特性设计分布式锁的一些方案,但在实际的开发中,如果需要使用到分布式锁,不建议去自己“重复造轮子”,建议直接使用Curator客户端中的各种官方实现的分布式锁,例如其中的InterProcessMutex可重入锁。

        接下来,我们一起来看一下Curator是如何实现分布式锁的。

3. 总结

内容完善中~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/327191.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysq之——分库分表

Mysq之——分库分表 简介分库分表的方式垂直分表垂直分库水平分库水平分表 图解:垂直分表与水平分表(分库类似)分库分表带来的问题 简介 分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成…

对接第三方接口鉴权(Spring Boot+Aop+注解实现Api接口签名验证)

前言 一个web系统,从接口的使用范围也可以分为对内和对外两种,对内的接口主要限于一些我们内部系统的调用,多是通过内网进行调用,往往不用考虑太复杂的鉴权操作。但是,对于对外的接口,我们就不得不重视这个…

C语言scanf()函数详解

目录 1. scanf()函数简介 1.1 函数原型 1.2 头文件 1.3 返回值 1.4 参数 2.格式说明符 3.输入格式控制 关于‘ * ’的例子 关于width域宽的例子 关于length长度修饰符的说明 4. 其他常见问题说明 4.1 scanf()函数连…

深入理解计算机系统(1):开始

计算机系统是由硬件和系统软件组成的,它们共同工作来运行应用程序。虽然系统的具体实现方式随着时间不断变化,但是系统内在的概念却没有改变。所有计算机系统都有相似的硬件和软件组件,它们又执行着相似的功能。 计算机系统 信息就是位上下…

从零学Java - 接口

Java 接口 文章目录 Java 接口1.接口的语法1.1 与抽象类的区别 2.如何使用接口?2.1 接口的使用规范 3.什么是接口?3.1 常见关系 4.接口的多态性5.面向接口编程5.1 接口回调 6.特殊接口6.1 常量接口6.2 标记接口 7.接口的好处 补充面向对象 七大设计原则 1.接口的语法 接口&a…

1-02VS的安装与测试

一、概述 对于一名C语言程序员而言,进行C语言程序的开发一般需要一个文本编辑器加上一个编译器就足够了。但为了方便起见,我们选择使用集成开发环境——Visual Studio(简称VS)。安装Visual Studio 下面讲一下如何安装VS&#xff0…

深度学习中的知识蒸馏

一.概念 知识蒸馏(Knowledge Distillation)是一种深度学习中的模型压缩技术,旨在通过从一个教师模型(teacher model)向一个学生模型(student model)传递知识来减小模型的规模,同时保…

CSS基础笔记-03选择器

CSS基础笔记系列 《CSS基础笔记-01CSS概述》《CSS基础笔记-02动画》 前言 在前面两篇博客中,我实际上已经使用过了选择器。但到底什么是选择器、有什么作用,我反而不能表达出来。因此,决定记录了我的学习和思考。 什么是选择器 selector…

软件测试/测试开发丨Selenium 高级控件交互方法

一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件(了解即可) www.selenium.dev/documentati… 二、ActionChains解析 实例化类ActionChains,参…

VLM,LLM等大模型如何应用于机器人控制(以强化学习为例)

VLM:视觉语义模型,准确识别图中有什么,处于什么状态,以及不同物体之间的关联。 LLM:语言大模型,可以针对当前的环境,自动生成可执行的任务,或者将人类指令重新分成可执行的子任务。…

MySQL之视图内连接、外连接、子查询

一、视图 1.1 含义 虚拟表,和普通表一样使用 视图(view)是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,数据库中只存放了视图的定义,而并没有存放…

函数图像化

函数图像化 在进行模型提取时,往往会需要选择拟合的函数,因此,了解函数的图像对于模型拟合提取有益,以下是常见的一些函数的曲线 1 二次函数 常见的耳二次函数曲线,转换x与y数量级差异仅一个数量级, 2 三…