redis之分布式锁

文章讲述了电商秒杀业务中如何在分布式环境下使用Redis的setnx命令实现锁管理,以及存在的问题如误删锁。通过引入Redisson工具,解决了锁的可重入性、重试获取、超时续约等问题,强调了在实际开发中Redisson的使用及其背后的原理。
摘要由CSDN通过智能技术生成

1、背景

我们知道很多电商都会有秒杀的业务,如果只有一台服务器承载不了同一时间千万用户的业务,所以需要多台服务器,单台业务中我们只操作一个数据库,对数据的库存做想要的删减和增加用户的秒杀信息。解决并发的场景使用的是synchronized锁,但是分布式集群的情况下,这个锁起不到作用,并且会出现以下超卖的情况所以需要依赖于redis的分布式锁。

5cb80ec54db543f289ed9329907f16e0.png

 

2、简单使用之setnx

在redis中有一个命令是setnx,含义是:如果key存在则返回0 如果key存在则增加后返回0,符合我们并发增加锁和删除锁的场景。

(1)使用的是setnx 增加锁

stringRedisTemplate.opsForValue().setIfPresent("lock:" + name,threadId, timeoutSec, TimeUnit.SECONDS);

(2)删除锁

stringRedisTemplate.delete("lock:" + name);

问题:

上述存在的问题是会存在误删锁的情况,如果两个线程,其中一个线程执行业务时间比较长,超过了其过期时间,则redis自动就会释放锁。另一个线程请求过来又可以获取锁了,第一个线程进入释放锁的逻辑,导致后续线程存在并发的情况了。

3、判断是否是自己线程则释放锁

上述情况的问题原因是由于没有在释放锁的时候,判断此线程是否是当前线程,如果是,则释放锁。为了做到同步,则使用lua脚本的方式来释放锁。以下是lua脚本,其中argv[1]表示当前线程的名称

if(redis.call('get', KEYS[1]) == ARGV[1])then
 return redis.call('del', KEYS[1])
end
return 0

4、redission由来

上述操作,redis也帮我们做到了,他提供了redisson工具这个内部内置了lua脚本,解决了之前锁的问题和限制,具体是哪些问题呢?

1、上述误删的问题

2、可重入锁 如果使用上述锁 是不能重入的 重入的含义是一个有锁的方法中 进入另一个需要锁的方法

3、可重试锁 是在等待一段时间内,看是否能获取锁,使用的是信号量和PubSub的功能来实现等待,唤醒。获取锁失败的重试机制

4、超时续约,redisson内部有过期释放机制默认值是30s,当releasetime=-1时才会有这个功能,当时间过期后会重置超时时间。

总结:

我们实际开发过程中直接使用的就是redisson。但是知其然要知其所以然。希望上述文章能帮助大家更好理解。

 

  • 26
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值