【Redis】Redis实现分布式锁

【Redis】Redis常见面试题(1)

在这里插入图片描述

文章目录

  • 【Redis】Redis常见面试题(1)
    • 1. 为什么要用分布式锁
    • 2. Redis如何实现分布式锁
    • 3. Redis接受多个请求模拟演示
    • 4. 使用Redis实现分布式锁会存在什么问题
      • 4.1 一个锁被长时间占用
      • 4.2 锁误删

【Redis】Redis常见面试题(1)

1. 为什么要用分布式锁

之前学到的锁,在分布式,微服务是不适用的,因为之前的锁针对的是本地线程,而分布式是跨机器的

而Redis作为一个独立的三方系统,其天生的优势就是可以作为一个分布式系统来使用,因此使用Redis实现的锁都是分布式锁!

在这里插入图片描述

2. Redis如何实现分布式锁

Redis实现分布式锁可以通过setnx(set if not exists)命令实现,当我们使用setnx创建键值成功则表明加锁成功,否则即加锁失败(需要等待锁释放,自旋/挂起等等…);del删除键值,表示锁释放

  • 也就是说,Redis实现锁机制没有那么的高深莫测和复杂,而是一个逻辑概念:
    • 一个锁🔐就是一个键值,争夺锁就是争夺对这个键值的设置权
    • 如果键值被设置了,则说明锁被占用
    • 如果键值不存在,则说明锁没被占用
  • 值是什么具体而论,对于争夺锁的机制而已,是存不存在比较重要
  • 而这个键值对也可以被看成普通的键值对,setnx和del不止用在分布式锁的实现,它们只是具有特殊含义的命令罢了
    • 又由于Redis天生支持分布式系统,所以这个键值可以被所有机器看到(满足了一个前提,所有机器可以setnx 和 del同一个键值),也就是这个锁🔐就是分布式锁

获得锁🔐:

127.0.0.1:6379> setnx lock1 true

在这里插入图片描述

再次获得这把锁:

在这里插入图片描述

在这里插入图片描述

就是个普通键值对~

释放锁🔐

127.0.0.1:6379> del lock1

在这里插入图片描述

再次释放锁:

在这里插入图片描述

那么我们用两个命令行操作redis,模拟两个线程,讲解Redis分布式锁的一些相关问题

在这里插入图片描述

在这里插入图片描述

3. Redis接受多个请求模拟演示

两个命令行“同时”尝试获取锁,总有一个会获取到锁

在这里插入图片描述

黑色命令行选择自旋等待锁:

在这里插入图片描述

直到白色命令行释放锁:

在这里插入图片描述

黑色命令行才获取到锁:

在这里插入图片描述

4. 使用Redis实现分布式锁会存在什么问题

4.1 一个锁被长时间占用

  1. 当一个应用突然奔溃、掉电、莫名其妙下线了,没来得及释放锁
  2. 可能会出现死锁,暂时不考虑可不可以重入锁的问题,N个线程M把锁的问题,也会导致死锁
    • 死锁参考此文章的死锁讲解:【JavaEE】多线程进阶问题-锁策略and死锁,CAS操作,Synchronized原理_s:103的博客-CSDN博客

怎么处理:

  • 设置超时时间
  1. setnx 和 expire搭配使用,不太好,因为这样这条语句就是非原子性的,如果超时时间设置上之前奔溃了,依旧解决不了问题

  2. Redis 2.6.12 版本之后,提供了一个强大的功能,可以让这个操作是原子操作:

    • 在这里插入图片描述

    • 127.0.0.1:6379> set lock true ex 30 nx
      
      • 可以参考后面的题词
      • ex time,单位为秒
      • px time,单位为毫秒
      • 不设置默认永不过期,但是不过期不代表不会被删除掉,这跟数据淘汰机制有关

在这里插入图片描述

4.2 锁误删

由于这个键值对是公共可见的,所以一个线程是可以释放别的线程的锁的!从代码上我们不会出现刻意的删除别的线程的锁的恶劣行为,但是会有一些不可避免的偶然事件场景下,会出现这个问题:

  1. 白色线程抢到了锁🔒,黑色线程自旋

在这里插入图片描述

  1. 但是白色线程执行花了35秒,锁已经自动释放了

在这里插入图片描述

  1. 黑色线程抢到了锁,要执行10秒

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

  1. 白色线程不知道锁被释放并且被抢走了,在第35秒的时候,严谨规范地释放了锁!
    • 即使锁过期了,这也只是Redis的机制,原应用的业务依旧继续执行,(不要误解为应用在Redis中执行!多个应用只是利用的Redis的分布式锁的机制!这里的黑色线程和白色线程只不过是区分两个线程的redis操作)
    • 黑线程不知道自己的锁被释放了,并且锁可能也被其他更多线程获取了,黑线程也可能会误删别人的锁,混乱起来了,线程安全问题大大暴露!

在这里插入图片描述

这有点像,ABA的问题,参考此文章的aba模块:【JavaEE】多线程进阶问题-锁策略and死锁,CAS操作,Synchronized原理_s:103的博客-CSDN博客

解决方法与之类似,(添加一个属性:一个标识或者版本号),保证释放锁是自己刚才抢到的锁!

  • 例如设置不一样的value

白色线程设置white,黑色线程设置black

也就是刚才的第四步,白色线程在释放锁之前,进行判断锁的归属:

在这里插入图片描述

ok,白色线程知道了,不能释放

但是并不是完全没有问题,这个操作是两步的,非原子性操作!

解决方案:

  1. 使用lua脚本,Redis可以识别的可保证原子性的脚本,写多长都是原子性的
  2. 项目使用Redisson框架,有支持原子性的分布式锁 -> 底层还是lua脚本,只不过你不用写,框架帮你写了
    • 一个复杂且好用的东西,总会有框架来方便使用😄

感兴趣的同学可以自行学习:

Redisson · GitHub


文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆


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

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

相关文章

vue2+element-ui批量导入方法并判断上传的文件是否为xls或xlsx

业务需求: 代码结构: <el-dialogtitle"批量导入":close-on-click-modal"true"close"close()":visible"true"width"35%":center"true"><div class"el-dialog-div"><!-- 头部区域布局 -…

【基本数据结构 四】线性数据结构:队列

学习了栈后,再来看看第四种线性表结构,也就是队列,队列和栈一样也是一种受限的线性表结构,和栈后进先出的操作方式不同的是,队列是FIFO的结构,也就是先进先出的操作方式。 队列的定义 队列这个概念非常好理解。可以把它想象成排队买票,先来的先买,后来的人只能站末尾…

软考知识汇总--结构化开发方法

文章目录 1 结构化开发2 耦合3 内聚4 设计原则5 系统文档6 数据流图6.1 数据流图的基本图形元素 7 数据字典 1 结构化开发 结构化方法总的指导思想是自顶向下、逐层分解&#xff0c;它的基本原则是功能的分解与抽象。它是软件工程中最早出现的开发方法&#xff0c;特别适合于数…

「C++程序设计 (面向对象进阶)」学习笔记・二

0、引言 本专栏的系列文章是在学习 北京邮电大学 崔毅东 老师的《C程序设计 (面向对象进阶)》课程过程中整理的。欢迎前往专栏了解更多相关内容~ &#x1f600; 有关于现代 C 的基本介绍&#xff0c;请前往《现代C基本介绍》&#xff01; &#x1f514; 先决条件 本专栏的系列…

定时器+BOM

9.定时器BOM 1.定时器 **概念:**重复执行一个函数 1.1setInterval() setInterval(“代码/函数”,时间,参数),返回定时器的序列号,默认从1开始 clearInterval(序列号)清除定时 <button class"start">开启定时器</button><button class"close…

通过Power Platform自定义D365 CE 业务需求 - 3. 使用Microsoft Power应用程序

Microsoft Power Apps是一个用于开发应用程序的无代码、无代码平台。Power应用程序可以在Dataverse之上配置为数据库。尽管您可以连接Salesforce、OneDrive、Dropbox等多种云源,但Dataverse也可以用作内部数据库来构建应用程序,并通过连接器连接其他数据源进行集成。 Power应…

Java开发之Redis核心内容【面试篇 完结版】

文章目录 前言一、redis使用场景1. 知识分布2. 缓存穿透① 问题引入② 举例说明③ 解决方案④ 实战面试 3. 缓存击穿① 问题引入② 举例说明③ 解决方案④ 实战面试 4. 缓存雪崩① 问题引入② 举例说明③ 解决方案④ 实战面试 5. 缓存-双写一致性① 问题引入② 举例说明③ 解决…

内存管理机制

aCoral内存管理机制 aCoral内存管理机制在伙伴系统基础上&#xff0c;采用了位图法方式提高内存分配和回收速度的确定性&#xff0c;更能满足系统实时性的需求。 aCoral内存管理机制分为两级&#xff0c;上一级采用改进的伙伴系统&#xff0c;负责确定要分配的内存的大小&…

数据分析综述

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

C#类与类库调用注意事项

类 创建一个类文件&#xff0c;myfunction.cs //静态类&#xff1a;直接引用、无需实例化 static public int jiafa(int V) //普通类&#xff1a;引用时需要实例化 public int jiafa(int V)using System; using System.Collections.Generic; using System.Diagnostics; using …

ChatGPT追祖寻宗:GPT-2论文要点解读

论文地址&#xff1a;Language Models are Unsupervised Multitask Learners 上篇&#xff1a;GPT-1论文要点解读 在上篇&#xff1a;GPT-1论文要点解读中我们介绍了GPT1论文中的相关要点内容&#xff0c;其实自GPT模型诞生以来&#xff0c;其核心模型架构基本没有太大的改变&a…

Vue中extend基本用法

1.Vue.extend(options) 参数: {Object} options用法&#xff1a; 使用基础Vue构造器&#xff0c;创建一个"子类"。参数是一个包含组件选项的对象。 data选项是特例&#xff0c;需要注意&#xff0c;在Vue.extend()中它必须是函数。 <html><head><tit…

读高性能MySQL(第4版)笔记08_创建高性能索引(上)

1. 索引 1.1. 键&#xff08;key&#xff09; 1.2. 存储引擎用于快速找到记录的一种数据结构 1.3. 当表中的数据量越来越大时&#xff0c;索引对性能的影响愈发重要 1.4. 在数据量较小且负载较低时&#xff0c;缺少合适的索引对性能的影响可能还不明显 1.5. 索引优化是对查…

C#__线程池的简单介绍和使用

/*线程池原理&#xff1a;&#xff08;有备无患的默认备用后台线程&#xff09;特点&#xff1a;线程提前建好在线程池;只能用于运行时间较短的线程。*/class Program{static void Main(string[] args){for (int i 0; i < 10; i){ThreadPool.QueueUserWorkItem(Download); …

【Redis】Redis作为缓存

【Redis】Redis常见面试题&#xff08;2&#xff09; 文章目录 【Redis】Redis常见面试题&#xff08;2&#xff09;1. 缓存2. Redis作为缓存2.1 缓存雪崩2.2 缓存穿透2.3 缓存击穿2.4 缓存雪崩、缓存穿透、缓存击穿的区别2.5 缓存预热2.6 如何保证缓存和MySQL双写一致 【Redis…

Java 设置免登录请求接口被拦截问题

1、在设置免登录时&#xff0c;前端将请求的路由添加到白名单后&#xff0c;请求接口还是被拦截到了&#xff0c;将请求接口也设置后还是会被拦截跳转到登录页面 通过JAVA 注解 Anonymous 进行设置匿名访问就可以了

【Unity编辑器扩展】| 自定义窗口和面板

前言【Unity编辑器扩展】| 自定义窗口和面板一、EditorWindow二、ScriptableWizard三、编辑器绘制3.1 文本输入3.2 空行3.3 滑动条、进度条3.4 枚举选择3.5 其他总结前言 前面我们介绍了Unity中编辑器扩展的一些基本概念及基础知识,还有编辑器扩展中用到的相关特性Attribute介…

华为云云耀云服务器L实例评测|服务器反挖矿防护指南

前言 本文为华为云云耀云服务器L实例测评文章&#xff0c;测评内容是 云耀云服务器L实例 反挖矿防护指南 系统配置&#xff1a;2核2G 3M CentOS7.9 之前的文章中『一文教你如何防御数据库恶意攻击』&#xff0c;我们讲到黑客如何通过攻击数据库来获取权限&#xff0c;以及我们…

pyarmor 加密许可证的使用

一 pyarmor 许可证的用处 文档&#xff1a;5. 许可模式和许可证 — Pyarmor 8.3.6 文档 试用版本有如下的限制&#xff1a; 加密功能对脚本大小有限制&#xff0c;不能加密超过限制的大脚本。 混淆字符串功能在试用版中无法使用。 RFT 加密模式&#xff0c;BCC 加密模式在试…

《确保安全:PostgreSQL安全配置与最佳实践》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…