Redis机制-Redis互斥锁、分布式锁

目录

一 互斥锁

二 分布式锁

Redis实现分布式锁

redisson实现分布式锁

可重入性:

主从一致性(性能差):


一 互斥锁

假设我们现在有一个业务要实现秒杀优惠券的功能,如果是一个正常的流程,线程之间应该是这样运作的。

线程1先查询优惠券,如果库存充足,那么扣减库存,然后线程2来查询优惠券信息,如果充足,那么就扣减库存,但是这只是理想的情况。

那么如果出现图2的这种情况呢?

线程1在查询优惠券信息的时候发现库存是充足的,线程2查询的时候也是充足的,他俩都可以进行减库存的操作,假如优惠券只剩1张了,那么谁得到这个优惠券呢?这就是业务中可能出现的问题。

此时就需要用互斥锁来解决问题了

如图,假如线程1在获取互斥锁以后,线程2来了之后就只能发起获取锁的请求,只有当线程1操作完了之后释放锁,线程2获取到锁,才可以进行接下来的操作,这样就不会出现库存超卖的情况。

但是还有一个问题,上面所说的这种情况是针对单个Redis服务器进行加锁的,但是实际的业务逻辑中可能会有多个用户,访问多个Redis服务器,那么这时候要怎么解决呢?

二 分布式锁

假设我的代码部署到了多个tomcat中,每一个tomcat操控一个JVM,此时8080的虚拟机知道8081的线程1也在同时访问优惠券信息吗?这显然是不知道的。

此时就需要用到一个独立于tomcat之外的分布式锁来进行判断

如图,当8080的线程1进行访问时,其余的端口和线程都不可以进行访问,此时就达到了分布式锁的效果,有效的解决了超卖问题。要注意,分布式锁是加在Redis上的,不是自己的代码中。

Redis实现分布式锁

Redis实现分布式锁主要是利用Redis的setnx命令

SET LOCK VALUE NX EX 10  //加锁
DEL key                  //释放锁

第一条代码是加锁并且给锁设置过期时间,第二行代码是删除锁。如果不给锁设置过期时间,那么就有可能产生死锁的现象。即线程1执行时间过长,线程2一直在等待锁释放。

redisson实现分布式锁

redisson中也有分布式锁的实现

RLock lock = redissonClient.getLock("lock");
try{
    boolean isLock = lock.tryLock(10,TimeUnit.SECONDS);
    if(isLock){
        System.out.println("执行业务");
    }
} finally{
    lock.unlock();
  }

首先,线程1获取到锁之后,然后去操作Redis,也会去通知看门狗系统,而看门狗系统会每隔释放时间(redisson默认30秒)/3去给锁续期,希望业务完成之前不要因为锁到期而引发线程安全问题,此时线程1执行完,线程2获取到锁就可以继续执行了。而加锁和设置过期时间都是基于lua脚本完成的,这样可以保证操作的原子性。

可重入性:

假设下图是线程1所执行的代码,在redis当中会按照哈希结构去进行存储,key为锁的key,value会存储一个键值对,键为线程名称,value为锁的次数默认为0,加一次锁就+1,释放一次锁就-1.

如上图,执行add1( )时,Thread1第一次加锁时,value会被改成1,当add2( )想获取锁时,此时Redis会进行判断,你是不是线程1来的,发现add2( )的线程名为Thread1,那么此时该锁可以重入的,value值会变成2,当add2( )执行完以后,释放锁,value又变为1,add1( )执行完以后,value变成0,此时的锁才是真正被线程1所释放了。

主从一致性(性能差):

如图,如果是在集群模式下的Redis服务器势必会有主节点和从节点,当线程1过来获取到一把锁时,主节点刚好宕机了,集群又重新选了一个主节点,线程2此时又获取到了和线程1同样的一把锁,这样就会产生锁冲突的现象。

针对这样的情况就要加红锁(RedLock):在多个Redis实例上加锁,而不是只在一个节点上进行加锁,这样就可以避免锁重复。

但是这样实现相对来说比较复杂,因此AP思想和CP思想(zookeeper)可以解决该问题。

所以说性能和复杂是负相关的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ThreadLocal为什么会导致内存泄漏?

问题引出: ThreadLocal是为了解决什么问题而产生的? ThreadLocal发生内存泄漏的根本原因是什么? 如何避免内存泄漏的发生?定义 为了解决多个线程同时操作程序中的同一个变量而导致的数据不一致性的问题。   假设现在有两个线程A…

【C++题解】1696. 请输出1~n之间所有的整数

问题:1696. 请输出1~n之间所有的整数 类型:循环 题目描述: 从键盘读入一个整数 𝑛n ,请循环输出 1∼n 之间所有的整数,每行输出 1 个。 比如,假设 n5 ,那么输出结果如下: 1 2 3 4 …

微调Llama3实现在线搜索引擎和RAG检索增强生成功能

视频中所出现的代码 Tavily SearchRAG 微调Llama3实现在线搜索引擎和RAG检索增强生成功能!打造自己的perplexity和GPTs!用PDF实现本地知识库_哔哩哔哩_bilibili 一.准备工作 1.安装环境 conda create --name unsloth_env python3.10 conda activate …

我用 Midjourney 的这种风格治愈了强迫症

在 Midjourney 能够实现的各种布局之中,有两种风格因其简洁、有序而独居魅力,它们就是平铺 (Flat Lay) 和 Knolling (Knolling 就是 Knolling, 无法翻译🤣)。要在现实生活中实现这样的美学效果并不容易,你需要精心挑选各种小物件&…

【JAVA WEB实用与优化技巧】如何自己封装一个自定义UI的Swagger组件,包含Swagger如何处理JWT无状态鉴权自动TOKEN获取

目录 一、Swagger 简介1. 什么是 Swagger?2. 如何使用 Swagger3. Springboot 中swagger的使用示例1. maven 引入安装2. java配置 二、Swagger UI存在的缺点1.不够方便直观2.请求的参数没有缓存3.不够美观4.如果是JWT 无状态登录,Swagger使用起来就没有那…

MVCC相关

文章目录 前情要点基于什么引擎并发事务产生的问题不可重复读和幻读区别Next-Key Lock的示例解决并发事务采用的隔离级别当前读(Current Read)快照读(Snapshot Read)参考 MVCC定义表里面的隐藏字段由db_roll_ptr串成的版本链ReadView可见性算法mvcc的可见性算法为什么要以提交的…

编译器 编译过程 compiling 动态链接库 Linking 接口ABI LTO PGO inline bazel增量编译

编译器 编译过程 compiling 动态链接库 Linking 接口ABI LTO PGO Theory Shared Library Symbol Conflicts (on Linux) 从左往右查找:Note that the linker only looks further down the line when looking for symbols used by but not defined in the current lib.Linux 下…

【C++题解】1697. 请输出n~1之间所有的整数

问题:1697. 请输出n~1之间所有的整数 类型:循环 题目描述: 从键盘读入一个整数 n ,请输出 n∼1 之间所有的整数,每行输出 1 个。 比如,假设读入 n5 ,输出结果如下: 5 4 3 2 1 输入&#xff1…

第199题|关于函数的周期性问题|函数强化训练(六)|武忠祥老师每日一题 5月24日

解题思路:解这道题我们要用到下面这个结论 f(x)连续,以T为周期时,原函数以T为周期的充分必要条件是: (A) sin x显然是以π为周期的,我们可以看到并不等于0,根据结论,A的原函数显然不是周期函数。 (B) 的…

移动端仪表盘,支持更多组件

05/22 主要更新模块概览 定位函数 快捷筛选 轨迹图表 时间组件 01 表单管理 1.1 【表单组件】- 表单关联新增支持自定义按钮样式 说明: 表单关联-关联数据按钮,原仅支持默认按钮样式,现增加关联数据按钮自定义功能,满…

【传知代码】掩码自回归编码器法(论文复现)

前言:在探索现代数据科学的前沿领域时,掩码自回归编码器法(Masked Autoencoder,简称MAE)无疑是一个引人注目的亮点。这一技术,凭借其独特的训练机制和卓越的性能,已经在图像识别、自然语言处理以…

《我的阿勒泰》观后感(二、返璞归真也是一种美)

看了李娟的小说《我的阿勒泰》逐渐悟到一个道理,返璞归真也是一种美,没必要每个人的人生三十年的年华,都去追求房子,车子等逐渐贬值的东西。人究竟应该追求怎样的一种活法? 什么是城市化?这是我听到的最好…

osgearth 3.5 vs 2019编译

下载源码 git clone --recurse-submodules https://github.com/gwaldron/osgearth.git 修改配置文件 主要是修改bootstrap_vcpkg.bat,一处是vs的版本,第二处是-DCMAKE_BUILD_TYPERELEASE 构建 执行bootstrap_vcpkg.bat vs中生成安装 vs2019打开bu…

spring boot打的包直接运行

Spring Boot 提供了一个插件 spring-boot-maven-plugin 把程序打包成一个可执行的jar包&#xff0c;直接执行java -jar xxx.jar即可以启动程序 1、引用 spring-boot-maven-plugin插件 <build><plugins><plugin><groupId>org.springframework.boot<…

LED显示屏的智能化发展与未来趋势

摘要&#xff1a;随着智能化技术的飞速发展&#xff0c;LED显示屏行业也迎来了新的变革。本文将探讨LED显示屏的智能化发展方向&#xff0c;包括人屏互动、大屏中控智能化&#xff0c;以及智能LED显示屏在不同领域的应用前景。 1、引言 在智能化浪潮的推动下&#xff0c;LED显示…

GPT-4o: 未来的智能助手

GPT-4o: 未来的智能助手 在这个信息爆炸的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们生活中不可或缺的一部分。作为OpenAI最新推出的语言模型&#xff0c;GPT-4o不仅继承了前几代模型的优点&#xff0c;还在多个方面进行了显著的提升。本文将带你深入了解…

家政预约小程序03分类管理

目录 1 创建数据源2 搭建导航菜单3 搭建小程序4 设置变量5 变量绑定总结 家政预约小程序里&#xff0c;在首页需要展示家政可以开展的各类业务。我们把业务按照类别进行划分&#xff0c;本篇我们介绍一下管理后台的维护功能以及小程序的展示功能。 1 创建数据源 为了管理和展示…

WiFi蓝牙模块开发配置过程中需要注意的细节

在很多产品的应用场景中&#xff0c;WIFI网络会给我们提供很多便捷&#xff0c;MCU开发中大多使用串口WIFI蓝牙模块来实现产品接入WIFI网络中。   具体的使用模型如下图所示&#xff1a;整个系统涉及到WIFI网络、手机、服务器平台以及我们设计的产品&#xff0c;一个完整的生…

uniapp+php服务端实现苹果iap内购的消耗性项目和非续期订阅项目,前后端代码加逻辑分析

前言&#xff1a;公司的项目app在上架苹果商店时发现人家要求里面的部分购买项目必须使用iap购买的方式&#xff0c;使用原本的微信支付方式审核不给通过&#xff0c;无奈只能重新研究这个东西。做起来还是有点麻烦&#xff0c;主要是网上的文章很少&#xff0c;不能直接硬抄。…

彩信JSON接口对接发送

随着通讯技术的飞速发展&#xff0c;传统的短信已经无法满足人们日益增长的沟通需求。在这样的背景下&#xff0c;群发彩信作为一种更为先进、更为丰富的信息传递方式&#xff0c;逐渐受到了企业和个人的青睐。那么&#xff0c;群发彩信应该怎么对接&#xff0c;又具体有哪些优…