分布式锁 -- 分布式锁的种类和原理

news2024/12/23 11:38:59

锁的种类

jvm进程锁和分布式锁

jvm进程锁

说明:jvm进程锁可以控制jvm内部多个线程的共享资源访问。常用的有synchronized和Lock ,异同点如下:

1、Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现

2、对异常的处理:
synchronized除了在流程走完释放锁,在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生
Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock 时需要在finally块中释放锁

3、中断锁:
Lock可以让等待锁的线程响应中断,当通过lockInterruptibly()方法获取某个锁时,如果不能获取到锁,只有进行等待的情况下,是可以响应中断的。而使用synchronized时,等待的线程会一直等待下去,不能响应中断。

4、获取到锁的通知:Lock可以知道有没有成功获取锁,而synchronized却无法办到

5、ReentrantLock和synchronized都是可重入锁




分布式锁

一、常用的分布式锁
基于数据库实现分布式锁
基于缓存(Redis/Redisson)实现分布式锁
基于Zookeeper实现分布式锁

二、分布式锁的条件
1、排他性:同一时间,只能有一个客户端获取锁,其他客户端不能同时获取锁
2、避免死锁:这把锁在一定的时间后需要释放,否则会产生死锁,这里面包括正常释放锁和非正常释放锁,比如即使一个客户端在持锁期间发生故障而没有释放锁也要保证后续的客户端能加锁
3、自己解锁:加锁和解锁都应该是同一个客户端去完成,不能释放别人的锁
4、可用性

三、数据库分布式锁
在数据库中创建一个表,并在字段上创建唯一索引,想要执行某个方法,就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。

四、Redisson分布式锁
实现思路:
获取锁时,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为一个随机生成的UUID,通过此在释放锁的时候进行判断。
获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。

在这里插入图片描述

可重入的原理:
使用hash的数据结构,存储当前锁的key下对应的每个线程的持有锁数量

五、Zookeeper分布式锁

定义锁:通过Zookeeper上的数据节点来表示一个锁,如/exclusive_lock/lock节点即可定义为一个锁

获取锁:需要获取锁时,所有客户端会试图通过调用create()接口,在/exclusive_lock节点下创建临时子节点/exclusive_lock/lock。zookeeper会保证在所有客户端中,最终只有一个客户端能够创建成功,那么就可以认为该客户端获得了锁。同时,所有没有获得锁的客户端就需要到/exclusive_lock节点上注册一个子节点变更的Watcher监听,以便实时监听到持有锁节点的变更情况

释放锁:以下两种情况会释放锁:

当前持有锁的客户端发生宕机,Zookeeper上的这个临时节点会被移除

正常执行完业务逻辑后,客户端主动将自己创建的临时节点删除

六、spring全局锁
springboot全局锁依赖

对应的实现方式的依赖 Redis/Zookeeper

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<!-- spring integration,实现redis分布式锁 -->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-redis</artifactId>
</dependency>

配置
Redis/Zookeeper连接配置

spring: 
  #Redis 连接
  redis: ***

依赖的实现方式的Configuration配置

@Configuration
public class RedisConfig {
    // 当前业务场景下,要加的锁的前缀,如对同一个seq操作加锁,则生成的锁的key:push_lock_seq_6166234
    public static final String LOCK_KEY_PRE = "push_lock_seq_";
​
    @Bean
    public LockRegistry lockRegistry(LettuceConnectionFactory redisConnectionFactory) {
        return new RedisLockRegistry(redisConnectionFactory, LOCK_KEY_PRE);
    }
}

使用


@Component
public class Operation {
    /**
     * 注入配置类中配置的bean
     */
    @Autowired
    private LockRegistry lockRegistry;
​
    /**
     * 业务逻辑
     */
    public void operation(){
        // ...
        Lock lock = lockRegistry.obtain(RedisConfig.LOCK_KEY_PRE);  // 获取锁对象
        lock.lock();    // 加锁,同步请求锁,如不设置,则默认的获取锁的阻塞时间为60S
        try {
            // TODO operation
        } finally {
            lock.unlock();  // 释放锁
        }
        // ...
    }
}

原理:
在这里插入图片描述

SpringIntegretion的优点

  1. SpringIntegretion实现了本地锁+Redis锁的组合,减少了同一个锁对Redis的压力

  2. 锁工厂基于SpringDataRedis, 只需一份配置

SpringIntegretion的缺点

  1. 未实现看门狗

  2. 仅支持非公平锁,不支持公平锁、RedLock、ReadLock、WriteLock

  3. 锁工厂基于SpringDataRedis, 如果分布式锁服务器的Redis实例和缓存服务分离配置会比较麻烦

如果同一个KEY的锁并发量比较大,且没有锁类型要求,可以考虑使用SpringIntegration,否则推荐使用Redisson

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年8月12日(星期六):骑行渔浦寒泉。

2023年8月12日(星期六)&#xff1a;骑行渔浦寒泉&#xff0c;早8:30到9:00&#xff0c; 大观公园门囗集合&#xff0c;9:30点准时出发 【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点: 大观公园门囗集合&#xff0c;家住南&#xff0c;东&#…

中级课程——CSRF

文章目录 案例原理挖掘 案例 原理 挖掘 挖掘详情 首先就是对目标敏感部位进行抓包分析&#xff0c;比如修改信息、转账、添加信息等等。通常一个数据包HTTP请求头里边都会有一个Referer&#xff0c;这个需要特别去验证。比如放到Burpsuit Repeater里边去测试&#xff1a;去掉…

基于Java+SpringBoot+Vue的数码论坛系统设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

灰度阈值变换之c++实现(qt + 不调包)

本章介绍灰度阈值变换的基本原理和实现方法&#xff0c;它用于产生二值图。 1.基本原理 我觉得不用过多介绍&#xff0c;就是一个普通得不能再普通的二值化操作 2.代码实现&#xff08;代码是我以前自学图像处理时写的&#xff0c;代码很粗糙没做任何优化&#xff0c;但很好理解…

海外跨境贸易全开源线上商城搭建--无货源一键铺货模式

要搭建一个海外跨境贸易全开源线上商城并实现无货源一键铺货模式&#xff0c;以下是一些步骤和注意事项&#xff1a; 1. 选择适合的开源平台&#xff1a;首先&#xff0c;需要选择一个适合的开源平台作为商城的基础架构。根据企业的需求和技术实力&#xff0c;选择一个稳定、功…

ubuntu 如何命令行打开系统设置(Wifi,网络,应用程序...)

关于GNOME GNOME 是一个自由、开放源代码的桌面环境&#xff0c;它运行在 Linux 和其他类 UNIX 操作系统上。它是 GNU 项目的一部分&#xff0c;旨在为 Linux 操作系统提供一个现代化、易于使用的用户界面。 GNOME 桌面环境包括许多应用程序&#xff0c;例如文件管理器、文本编…

Python 爬虫实战:驾驭数据洪流,揭秘网页深处

前言 随着互联网的发展&#xff0c;数据变得越来越重要&#xff0c;爬虫技术也越来越受到人们的关注。爬虫技术可以帮助我们自动化地抓取网络数据&#xff0c;从而提高数据的利用价值。但是&#xff0c;在爬虫过程中&#xff0c;很容易被目标网站识别出来&#xff0c;甚至被封…

多个QLabel中文字左右对其问题研究

众所周知&#xff0c;关于QLabel 中的文字对其方式&#xff0c;官方提供多种&#xff0c;具体可参考 AlignmentFlag&#xff0c;这里就不详细列举了。 实际开发中有这样一个需求&#xff1a;多个lab中&#xff0c;文字显示不同&#xff0c;长度不一&#xff0c;但想要实现视觉…

基于历史对比学习的时序知识图谱推理(AAAI2023)

知识图谱顶会小记 论文标题 Temporal Knowledge Graph Reasoning with Historical Contrastive Learning 论文链接 https://arxiv.org/pdf/2211.10904.pdf GitHub地址 https://github.com/xyjigsaw/CENET 关键词 Linked Open Data, Knowledge Graphs & KB Completi…

Java多线程(七)

目录 一、线程池参数介绍 二、线程池的工作流程 三、使用Executors创建常见的线程 一、线程池参数介绍 为了深入的了解线程池&#xff0c;这里就需要明白线程中的各种参数的含义。下述的图片中是来自于Java标准库中对线程池描述。 1.corePoolSize 与 maximumPoolSize 其中core…

机器学习-自定义Loss函数

1、简介 机器学习框架中使用自定义的Loss函数&#xff0c; 2、应用 &#xff08;1&#xff09;sklearn from sklearn.metrics import max_error from sklearn.metrics import make_scorer from sklearn.model_selection import cross_val_score from sklearn.linear_model …

Flowable-泳池泳道

目录 说明视频教程 说明 流程图描述一个过程的步骤&#xff0c;当这个过程涉及许多不同的人&#xff0c;部门或功能区域时&#xff0c;很难跟踪每 个步骤的负责人。解决此问题的一个有用方法是把流程图分栏&#xff0c;BPMN 中提供了泳池、泳道来支持 这种场景。泳池泳道在流程…

机器学习(十八):Bagging和随机森林

全文共10000余字&#xff0c;预计阅读时间约30~40分钟 | 满满干货(附数据及代码)&#xff0c;建议收藏&#xff01; 本文目标&#xff1a;理解什么是集成学习&#xff0c;明确Bagging算法的过程&#xff0c;熟悉随机森林算法的原理及其在Sklearn中的各参数定义和使用方法 代码…

国内什么牌子的ipad手写笔好用?适合绘画电容笔推荐

对于那些想要用ipad来学习的人来说&#xff0c;苹果Pencil是必不可少的。但是&#xff0c;Apple Pencil的价格真的太贵了&#xff0c;以至于很多人都买不起。所以&#xff0c;最好的办法就是选用一支平替的电容笔。本人从前几年就开始使用iPad&#xff0c;同时本身也是一位数码…

图 ML 中的去噪扩散生成模型

Denoising Diffusion Generative Models in Graph ML | by Michael Galkin | Towards Data Science (medium.com) 一、说明 AI DDPM 代表【"Adaptive Importance Density Power Mixture Model" 】即“自适应重要性密度幂混合模型”&#xff0c;是一种用于密度估计的机…

检测代理IP匿名程度的实用方法

在当今数字化的世界中&#xff0c;使用代理IP已成为保护个人隐私和增强网络安全的常见做法。然而&#xff0c;不同代理IP的匿名程度各异&#xff0c;有些可能具有较高的匿名性&#xff0c;而另一些则可能暴露了用户的真实身份和位置。 因此&#xff0c;了解如何检测代理IP的匿…

动态内存空间管理

欢迎来到我的 世界 ^ _ ^希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 文章目录 前言&#xff1a;动态内存是什么一、动态内存介绍&#xff1a;动态内存有关函数介绍1.malloc和free2.calloc函数3.realloc函数 二、一些常见的动态…

虹科案例 | 台积电为保证光罩运输质量选择MSR冲击振动记录仪!内含台积电工程师专访

晶圆运输需要注意什么&#xff1f; 晶圆运输是半导体制造过程中极为关键和敏感的一环。在晶圆运输过程中&#xff0c;需要注意以下几点&#xff1a; 1、静电防护 晶圆非常容易受到静电的干扰&#xff0c;因此在运输过程中需要遵守严格的静电防护措施。使用适当的静电防护包装…

数据库|同城双中心 DR Auto-Sync 主中心意外故障恢复

一、前言 最近&#xff0c;我一直在各个地方进行 TiDB 的 Poc 测试。在这些测试中&#xff0c;客户特别关注同城双中心或者两地三中心的架构体系&#xff0c;经常会找我了解 TiDB 灾备架构的实现方案和底层逻辑。基于客户对 RPO 0 的要求&#xff0c;我一般会向他们介绍 DR Au…

Flume原理剖析

一、介绍 Flume是一个高可用、高可靠&#xff0c;分布式的海量日志采集、聚合和传输的系统。Flume支持在日志系统中定制各类数据发送方&#xff0c;用于收集数据&#xff1b;同时&#xff0c;Flume提供对数据进行简单处理&#xff0c;并写到各种数据接受方&#xff08;可定制&…