关于分布式锁的一些总结

1、什么是分布式锁?

1.1、 概念

为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度。而这个分布式协调技术的核心就是来实现这个分布式锁

2、分布式锁的实现有哪些?

  • zookeeper:利用 Zookeeper 的顺序临时节点,来实现分布式锁和等待队列。Zookeeper 设计的初衷,就是为了实现分布式锁服务的。

  • Mysql(数据库):利用Insert 命令,当表中存在数据时,Insert失败,获取不到锁,成功则表明获取到锁;

  • Redis:利用 Redis 的 setnx 命令。此命令同样是原子性操作,只有在 key 不存在的情况下,才能 set 成功。

2.1、 通过 Redis 分布式锁的实现理解基本概念

分布式锁实现的三个核心要素:加锁、解锁、锁超时

1) 加锁

最简单的方法是使用 setnx 命令。key 是锁的唯一标识,按业务来决定命名。比如想要给一种商品的秒杀活动加锁,可以给 key 命名为 “lock_sale_商品ID” 。value设置成 1,表示库存。

当一个线程执行 setnx 返回 1,说明 key 原本不存在,该线程成功得到了锁;当一个线程执行 setnx 返回 0,说明 key 已经存在,该线程抢锁失败。

2)解锁

有加锁就得有解锁。当得到锁的线程执行完任务,需要释放锁,以便其他线程可以进入。释放锁的最简单方式是执行 del 指令。

3)锁超时

如果一个得到锁的线程在执行任务的过程中挂掉,来不及显式地释放锁,这块资源将会永远被锁住(死锁),别的线程再也别想进来。所以,setnxkey 必须设置一个超时时间,以保证即使没有被显式释放,这把锁也要在一定时间后自动释放。setnx 不支持超时参数,所以需要额外的指令。

2.2、由此产生的问题的一些思考

  • 思考1:锁超时时间设置的必要性

情景:首先线程A拿到了锁,但这个时候线程A挂掉了,锁就会一直存在。

  • 思考2:时间设置带来的影响

情景:

1)由于设置了超时时间,如果线程A,在规定时间内,没有处理完任务,它自动释放了锁,但实际还在占用资源。

2)线程B这个时候去申请锁,申请到了锁,如果执行的是和A不同的任务(如果相同的任务,导致数据异常)。

3)然后A完成了任务,执行删除锁的命令,实际删除的是B的锁。

  • 思考3:解决问题

1)首先解决删除别人的锁的问题

我们可以在删除的时候进行一个判断,看当前持有锁的线程是不是自己,如果是自己再删除

2)解决自动释放问题

可以用一个监听线程,去监听A锁的持续时间,一般当锁的时间不足2/3时,续时

  • 思考4:高可用

解决方案一:主从模式

主从模式的问题:如果在主库刚拿到锁的时候,挂了,从库顶上,会导致锁丢失。

解决:改用集群

解决方案二:集群

集群模式的问题:因为集群模式要给各个库都发送锁信息,各个库得到锁的时间不同,会导致锁的持续时间不同

解决:启用监听线程

其他分布式锁的也是类似的,做了一个总结图。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KX8zP0F4-1597712518087)(C:\Users\93584\Desktop\面经\锁.png)]

参考:

https://www.jianshu.com/p/a1ebab8ce78a

https://www.bilibili.com/video/BV1dQ4y1A7Nb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值