Redis分布式锁及Redisson的实现原理

news2024/10/6 14:28:53

Redis分布式锁

一。什么是分布式锁

在讨论分布式锁之前我们回顾一下一些单机锁,比如synchronized、Lock 等

锁的基本特性:

1.互斥性:同一时刻只能有一个节点访问共享资源,比如一个代码块,或者同一个订单同一时刻只能有一个线程去支付等。
2.可重入性: 允许一个已经获得锁的线程,在没有释放锁之前重新去获得锁
3.锁的获取和释放,锁的失效机制是避免死锁 的一个问题

分布式锁也是基于这些特性来实现的,只不过是在分布式环境中来实现的。

在这里插入图片描述

那什么是分布式锁呢:

分布式锁独立于业务服务的,是一种跨进程的,跨机器节点的一种互斥锁。保证多个机器节点对共享资源访问的一个排他性。

二。自己设计一个锁,如何实现

先分析一下需求:

1.只能有一个线程能同时执行互斥的资源
2.其他的线程执行的时候,如果有线程要执行的话,要么等待,要么报错

实现方案:

1.要有一个标记来标记一个线程是不是在执行
比如说小黑屋,如何保证一个小黑屋只有一个人,就是门,如果一个人进去之后把门锁住,那就能保证一个小黑屋只能有一个人了
单机锁中的synchronized 是把这个标记放到对象头的,JUC中的Lock实现的时候也是有一个state来标记的
2.这个标记是可见的。
也就是说小黑屋里一个人进去之后 得让所有人能获取到这个小黑屋里有没有人的最新结果
如何解决呢 可以用 volatile
3.获取 这个标记不能同时抢占成功,这一步必须是安全的。
也就是说一个人进小黑屋,至少分三步,进门,关门,锁门
如果说这三个操作不是原子性的话,一个人虽然进去了,但是还没有锁门,另外一个人也是可以进的,这样就不能保证互斥性
比如说JUC的Lock是怎么实现的 是通过cas(Compare And Swap 比较交换)实现的

三。Redis是怎么实现分布式锁的

1.标记
Redis key-value 结构 这个key就作为一个标记,这个key存在就说明有人在做,如果不存在就说明没人在做
2.可见性
也就是说我再get的时候,其他线程是不能set的

Redis中是如何保证的呢?单线程来实现的 因为必须要set完之后才能get set和get是顺序执行的

3.保证原子性

setnx 是单线程执行的 setnx 是一个原子性的指令

Redis获取锁与占有锁不是原子的,导致锁失效

为什么要原子性可以看下图:

在这里插入图片描述

4.保证原子性Redis还有两种方式

1.事务
multi 开启一个事务
exec 提交
discard 回滚
比如:

在这里插入图片描述

提交之后才能看到数据

在这里插入图片描述

回滚

在这里插入图片描述

在这里插入图片描述

事务中命令可以是原子的,但是不能根据中间的指令的结果来决定后续的逻辑,所以实现不了 if(exists(‘pay:111’) == 0) == true {set(‘pay:111’, 1)}

问题:两个开启的事务,同时修改一个值怎么办

用到了redis中的watch(监控)

如下:

在这里插入图片描述

watch id  //开启监控
multi //开启一个事务
incr id //将id加1 但是没有提交事务

如果此时有另外一个客户端 再将 id加1 如下:

在这里插入图片描述

此时回到第一个客户端 进行提交时 会报nil 也就是说不能执行

在这里插入图片描述

2.Lua脚本

四。redis的发布订阅机制

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息,发布者可以向指定的渠道 (channel) 发送消息,订阅者如果订阅了该频道的话就能收到消息,从而实现多个客户端的通信效果。

在这里插入图片描述

订阅的命令是SUBSCRIBE channel[channel …],可以订阅一个或多个频道,当有新消息通过PUBLISH命令发送给频道时,订阅者就能收到消息,就好像这样:

在这里插入图片描述

开启两个客户端,一个订阅了频道channel1,另一个通过PUBLISH发送消息后,订阅的那个就能收到了,靠这种模式就能实现不同客户端之间的通信。

五。问题

我们知道了redis的这些特性,那如果redis想要实现分布式锁,就得考虑几个问题:
1.重入锁怎么做,同一个线程能加锁多次
重入锁为了防止死锁,因为自己等待自己很容易死锁
重入锁需要做到以下三点:
1.互斥key 大Key
2.知道线程信息 field
3.保存重入次数 value hincrby(线程安全的)
Redis中的Hash完美的解决

2.假如30s锁会过期,但是业务还没有执行完,锁失效了怎么办

redission中的看门狗机制

redission 实现分布式锁

分布式锁的核心功能其实就三个:加锁、解锁、设置锁超时。这三个功能也是我们研究Redisson分布式锁原理的方向。

首先看一下redission 实现分布式的原理图

在这里插入图片描述

一。Redisson的源码

在使用Redisson加锁之前,需要先获取一个RLock实例对象,有了这个对象就可以调用lock、tryLock方法来完成加锁的功能

@Bean
    @Primary
    public Config redissonConfig() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + redisConfig.getHost() + ":" + redisConfig.getPort())
                .setPassword(redisConfig.getPassword())
                .setDatabase(redisConfig.getDatabase());
        return config;
    }
 
    @Bean
    @Primary
    public RedissonClient redissonClient(Config config) {
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
 
String lockKey = String.format(RedisKeys.APPROVAL_ACTION_KEY, approveParamDto.getProcessInstanceId());
RLock lock = redissonClient.getLock(lockKey);

RLock是一个接口,具体的同步器需要实现该接口,当我们调用redisson.getLock()时,程序会初始化一个默认的同步执行器RedissonLock

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

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

相关文章

python:将遥感数据使用matplotlib库绘制成图片

作者:CSDN @ _养乐多_ 本文将介绍使用matplotlib库绘制遥感数据成图片的代码。 文章目录 一、示例代码二、更换颜色条三、自定义颜色条四、分段离散颜色设置一、示例代码 要加载本地的TIFF数据并绘制图像,你可以使用Python中的rasterio库和matplotlib库。以下是一个示例代码…

【UE4】从零开始制作战斗机(中:飞机操控逻辑)

上一篇: 【UE4】从零开始制作战斗机(上:准备模型、定义函数和变量)_Zhichao_97的博客-CSDN博客 效果 步骤 1. 打开“BP_Jet”,在事件图表中添加如下节点 由于我们希望飞机一开始就是在空中飞行,所以一开…

数字孪生智慧路灯可视化系统 区域控制节能增效

前言 智慧灯杆是智慧城市建设的重要组成部分,可以完成照明、公安、市政、气象、环保、通信等行业数据信息的采集、发布和传输。同时,作为5g时代车联网、云网、通信网络建设的重要组成部分,智慧灯杆也将得到广泛应用。 建设背景 城市路灯存…

JVM常用参数和命令行工具

JVM参数类型 一:标准参数 - 所有的JVM实现都必须实现这些参数的功能,而且向后兼容 例: -help-server -client-version -showversion-cp -classpath 二:非标准参数 -X 非标准参数(-X)&#xff1a…

opencv缺陷检测

随着自动化生产设备的普及,工业机器人在各行各业的应用也越来越广泛,越来越多的生产线由自动化设备取代人工操作,实现自动化生产。在机器人分拣过程中,机器人不仅可以将不同规格和质量的产品准确地放入指定的托盘中,而…

MySQL 事物(w字)

目录 事物 首先我们来看一个简单的问题 什么是事务 为什么会出现事务 事务的版本支持 事务提交方式 事务常见操作方式 设置隔离级别 事物操作 事物结论 事务隔离级别 理解隔离性 隔离级别 查看与设置隔离性 注意可重复读【Repeatable Read】的可能问题&#xff…

Spring事务管理 -- Spring入门保姆级教程(五)

文章目录 前言六、Spring事务1.Spring事务简介2.入门案例--模拟银行间转账业务3.开启Spring事务的一般步骤4.Spring事务角色5.spring事务属性--rollbackfor6.入门案例进阶--转账业务追加日志7. Spring事务属性--事务传播行为 总结 前言 为了巩固所学的知识,作者尝试…

ZIP/RAR压缩包加密原理和解密方法

ZIP/RAR压缩包加密原理和解密方法 1、压缩包的概念 一般我们看到的压缩格式有.rar,.zip,等等有许多格式但主要压缩的作用就是让某一个文件占用空间小点。比如原来是50MB,可以压缩到30多MB。 压缩包的算法: 有许多不同的压缩格式例如&#…

【MySQL】-【数据库的设计规范】

文章目录 为什么需要数据库设计范式范式简介范式都包括哪些键和相关属性的概念 为什么需要数据库设计 范式 范式简介 在关系型数据库中,关于数据表设计的基本原则、规则就称为范式。可以理解为,一张数据表的设计结构需要满足的某种设计标准的 级别 。要…

第二届欧亚计算机科学与信息技术前沿国际会议

会议简介 Brief Introduction 2023年第二届欧亚计算机与信息技术前沿国际会议(FCSIT 2023) 会议时间:2023年9月15 -17日 召开地点:英国牛津 大会官网:www.ecfcsit.org 2023年计算机与信息技术前沿国际会议(FCSIT 2023)将围绕“计算机与信息技…

单词长度统计-列表

输入一段英文计算每个单词长度,统计不含非英文字符,列表输出。 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单…… 地址…

Java高并发核心编程(JUC)—线程详细笔记

进程 线程 线程方法 线程原理 线程状态 查看线程 进程 概述 进程:程序是静止的,进程实体的运行过程就是进程,是系统进行资源分配的基本单位. 一般来说,一个进程由程序段(包含代码、指令集合)、数据段(进程…

Gitlab的使用教程

Gitlab的基本介绍: Gitlab是利用Ruby on Rails 一个开源的版本管理系统,实现一个自托管的git项目仓库,可通过web界面进行访问公开或私有的项目。 与GitHub类似,Gitlab能够浏览源代码、管理缺陷和注释、可以管理团队对仓库的访问…

YSL赢麻了?SMI社媒心智品牌榜Top20公布:YSL破局夺魁,国货品牌现后起之秀

全文速览 1.数说故事联合用户说从美妆、彩妆、护肤三板块全新发布《SMI社媒心智品牌榜》。 2.圣罗兰、兰蔻、欧莱雅等法国高端美妆大牌垄断美妆《SMI社媒心智品牌榜》前三甲。 3.彩妆Top20榜单中,底妆产品稳居前列,色彩美妆占据一席之地。 4.护肤TOP…

Java面试知识点(全)-分布式微服务-zookeeper面试知识点

Java面试知识点(全) 导航: https://nanxiang.blog.csdn.net/article/details/130640392 注:随时更新 ZooKeeper是什么? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现&…

现在转行想学云计算?这些知识你需要提前掌握!

现在转行想学云计算?这些知识你需要提前掌握! 近年来,云计算技术和应用正铺天盖地向我们袭来,工作、生活、娱乐、教育、金融、科技、工业、农业等各个领域都有他的身影。什么是“云”?“云”是一个庞大的可容纳海量资源…

医疗科普系统和微信小程序开箱即用

一.下载地址 http://www.gxcode.top/code 二.项目说明 运行环境:jdk8tomcat8mysql5.7IntelliJ IDEAmaven微信开发工具 这是一个ssmvue微信小程序的医疗科普小程序,分为pc端和微信小程序端, pc端包括:管理员角色和学生角色。 管…

【LeetCode】168. Excel表列名称

168. Excel表列名称(简单) 思路 显然,这是一道从 1 开始的的 26 进制转换题。 对于一般性的进制转换题目,只需要不断地对 columnNumber 进行 % 运算取得最后一位,然后对 columnNumber 进行 / 算,将已经取得…

【项目源码】基层医院信息化管理系统HIS源码

医院信息系统(HIS)经历了从手工到单机再到局域网的两个阶段,随着云计算、大数据新技术迅猛发展,基于云计算的医院信息系统将逐步取代传统局域网HIS,以适应人们对医疗卫生服务越来越高的要求。 利用云计算、大数据等现代信息技术研…

Windows下安装docker

Windows下安装docker 1.安装WSL2 我的Windows版本如下: 版本 Windows 11 专业版 版本 22H2 1.1 检查能否安装 必要条件: Windows 10 对于 x64 系统:版本 1903 或更高版本,内部版本为 18362 或更高版本。对于 ARM64 系统&…