Redis分布式锁

分布式锁

【说明】

对于分布式锁,首先大家要理解下面5个问题:
1、什么是分布式锁?
2、在什么场景中会用到?
3、怎么实现分布式锁?
4、分布式锁应该具备那些条件?
5、单体应用上锁和分布式锁的对比

  • 什么是分布式锁?
    分布式锁:即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,控制的是多线程并发,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题,控制的是多进程(服务)。也就是说,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。
  • 在什么场景中会用到?
    在分布式系统中,不同的实例(服务/进程)是跨JVM的,但访问的资源并不会因为跨JVM而变成对应的多份,所以依旧存在多进程之间共享资源的问题,自然而然也就需要分布式锁来控制多进程的资源共享。
  • 怎么实现分布式锁?
    分布式锁的实现有:基于数据库实现分布式锁、基于Zookeeper实现分布式锁、基于reids实现分布式锁
  • 分布式锁应该具备那些条件?
    1、在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
    2、高可用的获取锁与释放锁
    3、高性能的获取锁与释放锁
    4、具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误)
    5、具备锁失效机制,即自动解锁,防止死锁
    6、具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败
  • 单体应用上锁和分布式锁的对比 此问题解答引用自知乎分布式锁
    在单机环境下,也就是单个JVM环境下多线程对共享资源的并发更新处理,我们可以简单地使用JDK提供的ReentrantLock对共享资源进行加锁处理。
    在这里插入图片描述
ReentrantLock lock = new ReentrantLock();
try {
    lock.lock();
    //处理共享资源
} finally {
    lock.unlock();
}

那如果是在微服务架构多实例的环境下,每一个服务都有多个节点,我们如果还是按照之前的方式来做,就会出现这样的情况:
在这里插入图片描述
这个时候再用ReentrantLock就没办法控制了,因为这时候这些任务是跨JVM的,不再是简单的单体应用了,需要协同多个节点信息,共同获取锁的竞争情况。

这时候就需要另一种形式的锁——分布式锁:
在这里插入图片描述
通常是把锁和应用分开部署,把这个锁做成一个公用的组件,然后多个不同应用的不同节点,都去共同访问这个组件(这个组件有多种实现方式,有些可能并不是严格意义上的分布式锁,这里为了方便演示,我们暂不做严格区分,统称为分布式锁)。

基于Redis实现分布式锁

redis分布式锁的主要解决的问题是多线程并发的情况下执行同一段对redis或者数据库的更新操作时产生的问题,举例:一个商品库存200,一个线程执行售卖操作,库存-1,另一个线程在此线程未执行完时也开始执行,此时,发生这种问题,当两个线程都执行完时,库存有199,但已经售出两件。

最初的代码,存在分布式锁的场景:
在这里插入图片描述

Redis分布式锁1.0

运用redis的setnx命令的性质,第一个线程过来时可以执行建立锁,后面线程来了之后不可以建锁,直接返回,第一个线程执行完之后删除锁即可。
在这里插入图片描述

分布式锁2.0

问题:当线程在执行减库存时发生异常导致最终无法执行删除锁,将导致整个程序停掉,大量请求阻塞
解决:在减库存操作使用try,删除锁使用finally,并设置锁10s的过期时间。

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

分布式锁3.0

问题:在2.0的基础上,当线程执行时间超过10s但未执行完时,此时锁已经自动删除了,而此时其他线程即可加锁成功,在经过5s,线程1结束,而线程2并未结束,此时线程1 会执行删锁,会把线程2 的锁删掉,当高并发情况时,会导致锁失效。(最主要的问题就是删除锁的限制)
解决:每个线程建锁时生成随机值设为锁的value值,在删除锁时判断此时锁的value值是否为建锁时的value值,为了保证原子性,可以使用lua脚本
在这里插入图片描述

分布式锁4.0

问题:在finally中判断的操作时同样有可能在这个时候锁超时自动解除锁了,也就是删除锁时的判断和操作不具备原子性。
解决:锁续命,也就是首先将建锁时将超时时间设为30s,在线程开始后会有一个分线程每隔10s判断一下当前的锁还在不在,如果在的话将锁的超时时间重新设为30s,直到最后线程结束删除锁。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智博的自留地

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值