分布式锁的理解

分布式锁讲解

为什么需要分布式锁?

​ 场景问题: 超卖问题

在这里插入图片描述

在此种情形下,没有做锁的处理会出现一种情况,例如:

在这里插入图片描述

一.Synchroized锁能否解决问题

我们需要明白一点:Synchroized锁是JVM内置的锁

许多项目都是集群架构,若加入Synchroized这种JDK级别和JVM级别的锁时不能的

如下图:如果我们使用nginx负载均衡,把请求发到不同的服务器,如第一个请求在tomcat1上,第二个请求在tomcat2上,这样Synchroized锁是不同的JVM上的,tomcat1的锁是用不了在tomcat2上的。
在这里插入图片描述

这种情况只有在高并发的情况下才会出现

所以 Synchroized是解决不了问题的

二.分布式锁

利用redis setnx来做分布式锁
在这里插入图片描述

因为redis是单线程操作,不管是不是单线程操作,都是要排队的

在这里插入图片描述

但是这么设置会有许多问题,例如异常,宕机怎么办?

处理方法

1.加入异常处理

try catch finally
在这里插入图片描述

新的问题:如果系统重启呢?没有删除掉key

2.设置超时时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gj7lIx6-1646725608002)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308103405015.png)]

这样写没有原子性,两行代码,如第一个设置的key没有怎么办

在这里插入图片描述

设置过期时间(也会出现问题,线程乱删除锁)

在这里插入图片描述

这种情况只要出现一次,锁就会失效!!!

处理方法:

  1. 先加锁(设置随机值)
  2. 比较锁的值(若相同则就是自己的锁,不同就是别人的锁

在这里插入图片描述

**场景问题:**网络卡顿的情况
在这里插入图片描述

3.锁续命

自动检测锁的过期时间

逻辑:在主线程里面开一个定时任务(分线程),定时检测锁的过期时间 ,如果要过期了就续命

redisson

分布式锁中的王者方案-Redisson - 悟空聊架构 - 博客园 (cnblogs.com)

<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.16.8</version>
</dependency>  

初始化

// 1. Create config object
Config config = new Config();
config.useClusterServers()
       // use "rediss://" for SSL connection
      .addNodeAddress("redis://127.0.0.1:7181");

// or read config from file
config = Config.fromYAML(new File("config-file.yaml")); 

使用

// 4. Get Redis based implementation of java.util.concurrent.locks.Lock
RLock lock = redisson.getLock("myLock");

RLockReactive lockReactive = redissonReactive.getLock("myLock");

RLockRx lockRx = redissonRx.getLock("myLock");

redisson分布式锁实现原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTYsC9ci-1646725608004)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308110927332.png)]

4…Lua脚本设置分布式锁:

  • 在服务器端
    • 优点:在后期使用直接调用
    • 缺点:修改不方便,占用资源
  • 在java端:
    • 优点:灵活
    • 缺点:每次都要发送lua脚本去服务器端,可能会造成网络通信延长

注意:使用了redis锁 可以保持可靠性,但会降低并发

缓存数据库双写不一致

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhb3Z5P9-1646725608004)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308144945165.png)]

缓存不一致

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TzbDOFBd-1646725608004)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308145229974.png)]

延迟双删 : 删缓存不止删一次,要删两次

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BqhzPQiR-1646725608005)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308145435840.png)]

缺点:

  • 能在一定程度上解决,但确定不了sleep的时间,无法确定是否能准确删除
  • 每一次修改数据都要删除两次缓存,提供了性能消耗

内存队列:将同一个商品的增删查改操作存到一个队列里

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RVhuKRkQ-1646725608005)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308150004387.png)]

并发问题串行化

难以实现,维护很多队列,容易OOM

加分布式锁(悲观锁)

都是操作库存Stock,共享资源

加了分布式锁可以,让并发问题串行化,比内存队列很容易维护

缺点:影响效率,每一次操作都会加锁阻塞,性能会非常低

加读写锁

大多数用户操作都是读多写少

读锁不互斥 写锁互斥

redisson 自带读写锁

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DAYAMqQM-1646725608005)(C:\Users\HP\AppData\Roaming\Typora\typora-user-images\image-20220308152036482.png)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值