【Redis实现分布式锁】

锁的种类

  • 单机版同一个JVM虚拟机内,synchronized或者Lock接口
  • 分布式不同个JVM虚拟机内,单机的线程锁机制不再起作用,资源类在不同的服务器之间共享了。

一个靠谱分布式锁需要具备的条件和刚需

  • 独占性:OnlyOne,任何时刻只能有且仅有一个线程持有
  • 高可用:若redis集群环境下,不能因为某一个节点挂了而出现获取锁和释放锁失败的情况
  • 防死锁:杜绝死锁,必须有超时控制机制或者撤销操作,有个兜底终止跳 出方案
  • 不乱抢:防止张冠李戴,不能私下unlock别人的锁,只能自己加锁自己释放。
  • 重入性:同一个节点的同一个线程如果获得锁之后,它也可以再次获取这个锁。

案例

在这里插入代码片

问题1:单机版没加锁

解决:在单机环境下,可以使用synchronized或Lock来实现。

问题2:分布式部署后,单机锁还是出现超卖现象,需要分布式锁

解决:
在这里插入图片描述

问题3:出异常的话,可能无法释放锁,必须要在代码层面finally释放锁

在这里插入图片描述

问题4:服务器宕机了

部署了微服务jar包的机器挂了,代码层面根本没有走到finally这块,没办法保证解锁,这个key没有被删除,需要加入一个过期时间限定key
在这里插入图片描述

问题5:设置key+过期时间分开了,必须要合并成一行具备原子性

在这里插入图片描述

问题6:删除了别人的锁

在这里插入图片描述

问题7:finally块的判断+del删除操作不是原子性的

解决:用lua脚本
在这里插入图片描述
截止到这里,基于单个Redis节点实现分布式锁

问题8:确保redisLock过期时间大于业务执行时间的问题

Redis集群与zookeeper集群对比

  • Redis 集群AP (互联网电商)
    redis异步复制造成的锁丢失
    比如:主节点没来的及把刚刚set进来这条数据给从节点,master就挂了,从机上位但从机上无该数据
  • zookeeper 集群CP(金融)

综上:

redis集群环境下,我们自己写的也不OK,直接上RedLock之Redisson落地实现
下面基于多个Redis节点实现高可靠的分布式锁
在这里插入图片描述
解锁
在这里插入图片描述

单机案例

加锁关键逻辑

在这里插入图片描述

解锁关键逻辑

在这里插入图片描述

多机案例

基于setnx的分布式锁有什么缺点?

在这里插入图片描述

  • 线程 1 首先获取锁成功,将键值对写入 redis 的 master 节点;
  • 在 redis 将该键值对同步到 slave节点之前,master 发生了故障;
  • redis 触发故障转移,其中一个 slave 升级为新的 master;
  • 此时新的 master并不包含线程 1 写入的键值对,因此线程 2 尝试获取锁也可以成功拿到锁;
  • 此时相当于有两个线程获取到了锁,可能会导致各种预期之外的情况发生,例如最常见的脏数据。
    我们加的是排它独占锁,同一时间只能有一个建redis锁成功并持有锁,严禁出现2个以上的请求线程拿到锁。危险的

容错率公式:

N = 2X + 1 (N是最终部署机器数,X是容错机器数)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值