redis分布式锁的思考

关于redis主节点宕机,导致分布式锁失效的思考:线程1先创建一个uuid,获取到key为A的锁,value为线程1创建的uuid,过期时间为3秒,再创建一个watchdog线程每隔一秒就去重置过期时间,在线程1执行完毕后去释放该锁。

可能遇到的情况:当前jvm进行gc,stw导致所有的线程都无法进行正常工作,如果时间过长,导致锁过期了,那么就需要在释放锁的时候去判断当前锁是否存在,不存在的话就抛出异常,若存在且是别的线程拿到的锁,也要抛出异常。

另一种极端的情况:若是redis主从集群,那么有可能在异步复制时,主节点返回成功给线程1后,并未将数据同步到从节点就宕机了,之后从节点被升级为主节点,线程2也去获取锁A成功,线程1也获取成功。

在上述情况中,我们需要做一些补偿措施,一般的补偿措施就是将事务回滚.
线程释放锁的时候应该判断当前锁是否存在,若不存在(1.key A过期,2.主节点未将key A同步到从节点就宕机了)就一定要回滚事务.

在上述线程1和2都拿到锁的情况下,有没有问题呢?其实是没什么大问题的,因为线程A释放锁的时候会发现持有者不是自己,释放不掉,这个时候怎么办?只需要做一下补偿就行了,例如将增删改的数据还原即可.

如何将数据还原呢?数据库数据容易还原,回滚事务就行,一些其它不支持事务的中间件,如redis,mq等,就需要特殊的补偿手段了,具体业务具体分析吧。

所以如果只有数据库事务,无论是单机还是集群redis,redis分布式锁可以放心使用,如果有其他中间件的数据产生,就得具体情况具体分析了.

总结一下:不出异常的情况下,redis锁其实是一个悲观锁,只有一个线程能进入。出异常的情况下(锁不存在了或者锁被其他线程获取了)redis锁其实是一个乐观锁,它将代码执行了一遍,但是最后发现锁的版本号(所属线程)变了,就无法提交数据了,需要回滚事务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值