【Redis】Redis实现分布式锁

2023-09-13 14:49:56

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

在这里插入图片描述

【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把锁的问题,也会导致死锁

怎么处理:

  • 设置超时时间
  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


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


更多推荐

GB28181学习(五)——实时视音频点播(信令传输部分)

要求实时视音频点播的SIP消息应通过本域或其他域的SIP服务器进行路由、转发,目标设备的实时视音频流宜通过本域的媒体服务器进行转发;采用INVITE方法实现会话连接,采用RTP/RTCP协议实现媒体传输;信令流程分为客户端主动发起和第三方呼叫控制两种方式,本文主要介绍客户端主动发起的方式;应具有媒体流保活机制;流程客户

第二十七章 Classes - 引用其他类成员

文章目录第二十七章Classes-引用其他类成员引用其他类成员第二十七章Classes-引用其他类成员引用其他类成员在方法中,使用下面的语法来引用其他类成员:要引用ObjectScript中的参数,使用如下表达式:..#PARAMETERNAME只能使用ObjectScript直接访问参数。要从Python访问参数,请

助力工业物联网,工业大数据之服务域:可视化工具Grafana介绍【三十八】

文章目录前言08:可视化工具Grafana介绍09:可视化工具Grafana部署10:Grafana集成Prometheus11:Grafana集成MySQL监控前言项目所需工具:链接:https://pan.baidu.com/s/1sIa8nninf2Fz6YqE3vUpqQ?pwd=5wr3提取码:5wr3–来自

Android 匿名共享内存的使用

注:本文内容转载自如下文章:Android匿名共享内存的使用AndroidView的绘制是如何把数据传递给SurfaceFlinger的呢?跨进程通信时,数据量大于1MB要怎么传递呢?用匿名共享内存(Ashmem)是个不错的选择,它不仅可以减少内存复制的次数,还没有内存大小的限制。这篇文章介绍在Java层如何使用匿名共

SkyWalking9.5.0安装与SpringBoot性能链路监控

文章目录1、下载安装1.1、安装Elasticsearch存储1.2、安装SkyWalking服务器端2、监控微服务2.1、监控SpringBoot微服务2.1、监控SpringCloudGateway网关Skywalking是分布式系统的应用程序性能监视工具,专为微服务,云原生架构和基于容器(Docker,K8S,M

PoE交换机出现不稳定的原因有哪些?

带有供电设备的PoE交换机给使用者带来了方便,因此被广泛应用。然而,很多使用商反映他们所使用的PoE交换机不稳定。那么,PoE交换机出现不稳定的原因有哪些?首先需要考虑的是数据传输的距离。尽管PoE供电交换机具有方便灵活的特点,但其供电距离不能超过100米。网线同时传输电力信号和数据信号,但电力信号的传输距离没有限制,

Python办公自动化之PDF

Python操作PDF1、Python操作PDF概述2、批量拆分3、批量合并4、内容提取(文字)5、提取内容(表格)6、提取图片7、PDF添加水印8、加密与解密1、Python操作PDF概述Python操作PDF主要有两个库:PyPDF2和pdfplumberPyPDF2是一个用于处理PDF文件的Python第三方库官

Unity的Resources类:从基础到高级的全面指南

前言Unity中的Resources类为开发者提供了一个方便的方式来加载和管理运行时资源。尽管它的使用简单直观,但为了充分发挥其潜力和避免常见的陷阱,还是需要对其有一些深入了解。Resources类简介Resources类是Unity中的一个静态类,它提供了方法来加载存储在特定“Resources”文件夹内的资源。这些

AI大模型服务应用场景

大模型是指模型具有庞大的参数规模和复杂程度的机器学习模型。在深度学习领域,大模型通常是指具有数百万到数十亿参数的神经网络模型。这些模型通常在各种领域,例如自然语言处理、图像识别和语音识别等,表现出高度准确和广泛的泛化能力。伴随基于大模型发展的各类应用的爆发,尤其是生成式AI,为用户提供突破性的创新机会,打破了创造和艺术

【爬虫实战】用python爬今日头条热榜TOP50榜单!

文章目录一、爬取目标二、爬取结果三、代码讲解四、技术总结五、演示视频六、附完整源码一、爬取目标您好!我是@马哥python说,一名10年程序猿。今天分享一期爬虫案例,爬取的目标是:今日头条热榜的榜单数据。打开今日头条首页,在页面右侧会看到头条热榜,如下:爬取以上6个关键字段,含:热榜排名,热榜标题,热度值,热榜标签,热

SpringCloud Gateway--网关服务基本介绍和基本原理

😀前言本篇博文是关于SpringCloudGateway的基本介绍,希望你能够喜欢🏠个人主页:晨犀主页🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰如果文章有什么需要改进的地方还请大佬不吝赐教

热文推荐