redis分布式锁的应用

news2025/2/26 0:28:34
redis 作为分布式锁的东西 分布式锁的应用
redis,zk,数据库这些都可以实现分布式锁
我们今天主要基于redis实现的分布式锁,而且要求性能要好
基于一个小的业务场景来说,就比如说秒杀中的减库存,防止超卖

在这里插入图片描述

这种代码就会有并发问题,比方说3个线程  同时查出来 之后会set 299  此时就超卖了
这就是我们典型的超卖问题,我们可以加锁,比如说我们常见的sy,JVM进程级别的锁

在这里插入图片描述

这样就可以解决我们的问题,如果说我们此时上线部署之后就一台服务器,也就一个tomcat 
单机环境 是没有问题 假设我们做集群项目的时候 此时就会出现问题
我们的项目基本上都是 基于nginx 进行转发,利用nginx做负载均衡,
在nginx的upstream中配置负载均衡的地址

在这里插入图片描述

一般来说我们都会搞这些集群架构部署,这种场景下我们jvm 级别锁就不可用了
我们可以模拟高并发场景利用jmeter基于高并发下发请求
jmeter--->nginx---->tomcat1/tomcat2
发现如果此时利用jvm级别的锁就会出现问题

在这里插入图片描述

一般情况下这种问题要解决的话 就用分布式锁 分布式锁 可以用redis
我们一般使用redis的setnx来实现分布式锁
基于setnx命令我们就可以实现一个分布式锁,在redis这边 只会有1个请求执行成功
这样我们就写完了

在这里插入图片描述

我们基于这种简单的setnx 实现的分布式锁有什么问题呢
Q1 如果我第一个线程拿到锁执行一半的时候 就会抛异常 抛异常之后 我就不会delete掉了
这个时候就相当于死锁了,key永远在redis中  其他线程要想来执行就会执行不成功

在这里插入图片描述

我写个try catch finally 意思是如果跑异常了 我还可以执行redis.delete 	
如果现在执行一半后 客户端宕机了,或者被运维重启了,呢么此时finally也是不能被执行的,我们可以设置一个超时时间,比方说10s,

在这里插入图片描述

我们可以加个超时时间,意味着如果你业务宕机了,过段时间 redis内部自己就释放锁了
如果并发特别大的情况下.这种代码也会造成超卖,在并发情况下 接口的响应可能会变慢

如果线程一执行了一半,超时时间到了, 这个时候线程2就会进来,然后此时线程一就会吧线程2的这个锁解开
线程1 删除(释放了)了线程2的锁  此时就会出现问题
出这个问题的根本点就在于  我自己加的锁被别人释放了

在这里插入图片描述

我们可以加个uuid就是说 我只能释放我自己加的锁,这个时候的代码就很完善了

在这里插入图片描述

假设一个线程枷锁成功了执行到这行代码的时候,卡顿一会,我们的10s到期了
其他线程又可以基于这个Lock进行加锁,这个时候线程1还是释放了线程2的锁
所以我们要保证这2行代码的原子性

我们的业务没有执行完毕 锁的超时时间就结束了
针对于分布式锁 有个锁续命机制 
分线程给锁进行续命,判断主线程有没有业务执行完毕,如果没有结束就续命
每过10s之后就续命,我的主线程一直执行 我的锁就不会失效,因为他一直被分线程做续命操作
以后我主线程要是把锁释放了,分线程会判断锁还被主线程持有 如果持有 就会做续命操作
如果不持有就不再跑任务了
Redisson  就实现了这种机制 

在这里插入图片描述

lock.lock 就可以获取得到锁了
Lock.unLock 加锁 解锁
https://www.cnblogs.com/xiaoyangabc/p/16906922.html
redis枷锁的核心流程, 假设有2个线程同时都是一个key执行  redis调用他的lock方法
只有1个线程执行成功,假设线程1执行成功。 线程2 执行没有成功
他会whlie循环自璇  尝试加锁
线程1 加锁成功 他会另外开启一个分线程,分线程就会对这个key 进行续命,
这就是整个redis分布式锁续命的核心业务流程

在这里插入图片描述

redis分布式锁底层是基于Lua脚本来写的,
lua脚本,减少网络开销。可以批量执行redis命令,类似于管道可以把一批命令打包发给redis 服务端去执行
比如说原来有4条命令,我就需要发送4次远程交互(网络调用)
但是我用管道或者lua脚本的话 就只需要一次网络调用
对于Lua脚本也一样,假设我有10条redis命令,我也可以放到lua脚本来一次性发给服务端去执行
lua脚本是支持原子操作的,一段Lua脚本,要么同时成功,要么同时失败
lua脚本都执行完毕 之后 其他命令才可以执行(因为redis服务端是单线程来执行任务的)
我这个命令执行的中间是不可以被其他线程插入的
Lua  支持事务在redis中可以执行lua脚本
用lua脚本是个原子操作

在这里插入图片描述
在这里插入图片描述

redis分布式锁的原理,当多个线程进行抢锁时候,只有一个线程来设置成功,其他没有抢到锁的线程就会while自旋尝试加锁,通过lua脚本进行加锁,加锁成功后就会对其进行续命,加锁失败就会自璇,续命锁
(Lua脚本进行续命) 每次续命1/3(判断主线程持有的呢吧锁是否还存在,如果存在我就进行续命,吧主线程的超时时间重新设置为30S ,如果不存在,我就结束)

说白了redis实现分布式锁的核心东西也就完成了,基本上是基于Lua来实现的  借助redis的单线程帮我们实现原子性.来解决并发问题

当我们其他线程如果没有加锁成功,lock 没有加锁成功会怎么办.假设有10个线程while循环枪锁 他的cpu 就会100%,如果说我们redis 没有抢到锁 他自选再去加锁 他是怎么来做的
其他线程会返回锁剩余加锁时间的剩余时间 并且阻塞让出cpu

比如说第一个线程执行了5S之后
假设我我第二个线程会尝试的过来加锁 如果没有加锁成功会再这里等25S  阻塞等待会让出cpu
25s过后之后再尝试加锁while循环间断性的加锁
假设有1000个线程来了同时超时 同时while循环  此时是非公平锁 也就是redis 默认 是非公平锁

在这里插入图片描述

所以 多个线程来抢锁时,底层会基于lua脚本进行加锁,但是只有一个线程来加锁成功,抢锁成功后后台开启一个分线程来对其进行续命,其他线程如果没有抢到锁 会while尝试加锁 但是 并不是死循环
而是会阻塞等待,返回第一次尝试加锁返回的时间,并且此时会让出cpu片段

如果此时业务时间比较快,快速吧这把锁释放了. 呢我其他线程不能一直阻塞 在解锁的方法中有一个唤醒机制 通过redis的发布订阅 他会往Queue发消息
没有加锁成功的线程会去监听Queue,呢么其他线程就会唤醒阻塞  继而继续while循环继续抢锁
 

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

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

相关文章

C++动态规划算法的应用:得到 K 个半回文串的最少修改次数 原理源码测试用例

本文涉及的基础知识点 动态规划 题目 得到 K 个半回文串的最少修改次数 给你一个字符串 s 和一个整数 k ,请你将 s 分成 k 个 子字符串 ,使得每个 子字符串 变成 半回文串 需要修改的字符数目最少。 请你返回一个整数,表示需要修改的 最少…

VS Code打造Julia IDE

文章目录 运行和调试Workspace绘图选项卡代码编辑 搜索并下载Julia插件后,左侧工具栏会出现Julia的三圆图标,点进去之后分为Workspace, Documentation以及Plot navigator三个子窗。 运行和调试 打开.jl文件后,其右上角会出现一个三角形的符…

【洛谷算法题】P3954-成绩【入门1顺序结构】

👨‍💻博客主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P3954-成绩【入门1顺序结构】🌏题目背景🌏题目描述&#…

【1++的Linux】之文件(三)

👍作者主页:进击的1 🤩 专栏链接:【1的Linux】 文章目录 一,磁盘结构二,磁盘的抽象结构三,文件系统四,文件的增删查改五,软硬链接六,动静态库1. **动态库和静…

Socket实现服务器搭建

一、前言: Socket上篇文章已经介绍过了 他是实现网络编程的基础 。 在服务器模型中通常都是多个客户端一个服务器端,那么服务器是如何处理多个客户端的请求? 1.顺序处理 依次处理--效率低下 2.并发处理 2.1 多线程并发(线程池…

《向量数据库》——Zilliz X Dify.AI ,快速打造知识库 AI 应用

Zilliz 大模型生态矩阵再迎新伙伴!近日,Zilliz 和 Dify.AI 达成合作,Zilliz 旗下的产品 Zilliz Cloud、Milvus 与开源 LLMOps 平台 Dify 社区版进行了深度集成。 01. Zilliz Cloud v.s. Dify Dify 作为开源的 LLMs App 技术栈,在此前已支持丰富多元的大型语言模型的接入,…

解密Java中神奇的Synchronized关键字

文章目录 🎉 定义🎉 JDK6以前🎉 偏向锁和轻量级锁📝 偏向锁📝 轻量级锁📝 自旋锁📝 重量级锁🔥 1. 加锁🔥 2. 等待🔥 3. 撤销 🎉 锁优化&#x1f…

将字符串中的数据按指定分隔符分割依次存入一维数组中 numpy.fromstring()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将字符串中的数据 按指定分隔符分割 依次存入一维数组中 numpy.fromstring() [太阳]选择题 请问以下代码中执行语句输出结果依次是? import numpy as np str1 "1.0 2.0 3.…

力扣第55题 跳跃游戏 c++ 贪心 + 覆盖 加暴力超时参考

题目 55. 跳跃游戏 中等 相关标签 贪心 数组 动态规划 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标,如果可以,返回 true &…

【算法训练-动态规划 四】【子序列类型问题】连续子数组的最大和

废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【动态规划】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…

架构设计系列5:如何设计高可用架构

#1024程序员节|参与投稿,赢限定勋章和专属大奖# 当今的数字时代,高可用架构已经成为了现代应用和服务的基石。无论是企业级应用、云计算平台还是互联网服务,高可用性都是确保系统在面临各种挑战时保持稳定运行的关键要素。 本文…

计算机算法分析与设计(19)---回溯法(装载问题)

文章目录 1. 题目描述2. 算法思路3. 代码编写 1. 题目描述 2. 算法思路 1. 思路: 容易证明,如果一个给定装载问题有解,则采用下面的策略可得到最优装载方案。 (1) 首先将第一艘轮船尽可能装满。(2) 将剩余的集装箱装上第二艘轮船。 2. 将第一…

基于springboot实现基于Java的超市进销存系统项目【项目源码+论文说明】

基于springboot实现基于Java的超市进销存系统演示 摘要 随着信息化时代的到来,管理系统都趋向于智能化、系统化,超市进销存系统也不例外,但目前国内仍都使用人工管理,市场规模越来越大,同时信息量也越来越庞大&#x…

Xilinx的FIR滤波器IP的设计与仿真

平台:Vivado2021.1 芯片:xcku115-flva1517-2-i (active) 语言:VerilogHDL 参考文件:pg149.下载地址 FIR Compiler LogiCORE IP Product Guide • FIR Compiler (PG149) • 阅读器 • AMD 自适应计算文档门户 (xilinx.com) FI…

【漏洞复现】panalog日志审计系统任意用户创建漏洞和后台命令执行

漏洞描述 panalog为北京派网软件有限公司,一款流量分析,日志分析管理的一款软件。存在任意用户创建漏洞和后台命令执行漏洞,可先通过任意用户创建,然后进行后台命令执行,获取服务器权限。 免责声明 技术文章仅供参考,任何个人和组织使用网络应当遵守宪法法律,遵守公…

怎么保护公司文件安全

怎么保护公司文件安全 无纸化办公时代,无论是企业还是个人在生活的方方面面都依赖于对电子化软件以及设备的使用。尤其是对于企业而言,在日常办公中产生的相关电子文件都是以电子文档的形式存储在电脑上。 下载试用安企神数据防泄密软件 若企业未实施…

力扣刷题 day53:10-23

1.二进制表示中质数个计算置位 给你两个整数 left 和 right ,在闭区间 [left, right] 范围内,统计并返回 计算置位位数为质数 的整数个数。 计算置位位数 就是二进制表示中 1 的个数。 例如, 21 的二进制表示 10101 有 3 个计算置位。 方…

Uncaught TypeError: Cannot use ‘in‘ operator to search for ‘path‘ in undefined

Uncaught TypeError: Cannot use ‘in’ operator to search for ‘path’ in undefined 报错如下: Uncaught TypeError: Cannot use in operator to search for path in undefinedat resolve (vue-router.esm-bundler.js:2882:13)at pushWithRedirect (vue-router…

Java将djvu文件转成pdf

需求来源 迫于有部分资源是djvu格式的文件,需要预览这部分文件,web端无法直接预览djvu,所以需要将djvu转成pdf。 转换方法 简单来说就是先把djvu文件转换成tiff文件,再将tiff文件转换成pdf文件。 Ubuntu服务器 如果服务器是U…

【软考-中级】系统集成项目管理工程师-项目收尾管理历年案例

持续更新。。。。。。。。。。。。。。。 目录 2017 下 试题三(17分)背诵整理1. 项目总结会议一般讨论的内容2. 系统文档验收所涉及的文档都有哪些 系列文章 2017 下 试题三(17分) 阅读下列说明,回答问题 1至问题 4,将解答填入答题纸的对应栏内     …