您当前的位置: 首页 >  分布式

星夜孤帆

暂无认证

  • 3浏览

    0关注

    626博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

分布式锁原理

星夜孤帆 发布时间:2021-03-20 17:07:25 ,浏览量:3

一、分布式锁基本原理

比如,我们现在有这么多商品服务,现在都要查数据库,现在我们约定只有一个人能查数据库,查完以后放到缓存里面。

这样呢,所有服务都要进来,需要抢占一个锁,本地情况下,我们可以使用语法比如synchronize(this)锁住当前对象,只要大家用的是一个对象,就能锁住了。

在分布式情况下也一样,我们this在分布式情况下,肯定没得用。

但是,我们可以考虑现实生活中的一个例子,比如,我们几千个人都去上公共厕所,里面只有一个坑位,那如何保证他们有序的进行,就是说,只要我进来了,我就给这个厕所上把锁,那别人就不能进来了。然后,上完以后,再出门解锁,这样其他人又能进来了。 

所以,我们分布式锁,也是这个思想原理,所有的商品服务,无论你是哪一个实例,大家都去一个公共的地方占锁,如果占到了锁,就去执行业务,如果没有站到锁的,那等待一下。

当我们业务执行完了以后,然后,释放锁,这样别人就可以占到这个锁了。

我们说的这个占坑,可以去任何一个地方去占,只要大家都去公共的一个地方,比如大家都去数据库,哪怕给数据库里面插入一条记录,如果这个人插入进去了,说明是成功的,如果插入的时候,看到已经有记录了,他就不能插入成功。

1.1 使用redis测试

redis中文文档

分布式锁的基本原理,我们都尝试去一个地方占坑,能占成功就会返回ok,大家都用同一个key保存一个东西,看能不能保存成功就行了。

二、分布式锁演进-阶段一 2.1 思想

大家想要获取锁,都去redis里面占坑,假设1000个请求全进来,都先去执行第一步,全部给redis发布setnx命令获取锁,也就是说没有lock的时候,我就占,这10000个肯定只有一个能占成功。

占成功了,就获取到锁,执行业务,执行完以后,删除锁,结束。

没占成功我们可以等一下,然后,重试。

2.2 问题

假如,我们业务代码,在这执行期间,出现了异常,导致程序抛异常直接退出了,都没有执行删锁代码,别人想要再来获取锁,就没有这个坑位了。

所以,这就导致了我们的死锁问题。

假如,我把删锁代码放到finally里面,这样异常也能删除。但是还有另外一种情况,就是我们的这个代码不是由于异常崩了,而是,我们代码正好执行到这,准备执行删锁的时候,我们机器断电了,我们没有执行删锁这段代码,相当于redis又没有删除锁,别人又占不到这个坑位了。

这就是我们说的第一个最严重的问题,如果我们解锁失败就会导致死锁。

解决这个问题的办法是什么?

我们可以给这个锁,设置一个自动过期时间。

三、分布式锁演进-阶段二 3.1 思想

为了解决死锁的问题,我们就可以给锁设置过期时间,比如30s,30s以后它会自动删除,即使我们执行业务代码,中间出现了问题,也没关系,redis会自动帮我们删除这个锁。

3.2 问题

加锁我们在设置过期时间前,出现异常或断电了,相当于我们过期时间没设置上,同样也会造成死锁。

如果加锁,和设置过期时间,是一个原子操作,就是我给redis,让它占锁的同时,加上过期时间,只要能返回ok,redis里面就说明已经加上锁,并设置上过期时间了。

返回不了,那就是加锁失败。所以,这一块失败的原因,就是我们获取锁和设置过期时间不是原子的。

四、分布式演进-阶段三 4.1 思想

我们业务代码执行成功,就来删锁,但是,假设我们当时锁设置的过期时间为10s,由于我们业务代码很耗时,比如我执行了30s,等我将要去删锁的时候,我们之前设置的锁其实已经过期了,redis里面已经没有它了。我们想要去删,我们想要去删除一个已经没有的数据还算好的,最坏的情况是这样的,别的线程看到你的线程过期了,然后,占了这个锁,然后,当你执行删锁的时候,却把别人的锁给删除了。

解决:

我们需要保证删锁的时候,删的不是别人的锁,怎么办?我们可以在占锁的时候,值指定为一个uuid,这个uuid每个人都不一样,保证每个人匹配是自己的锁才删除。

最下面的delete多余

五、分布式锁演进-阶段四 5.1 思想

5.2 问题

如果正好判断是当前值,正要删除锁的时候,锁已经过期,别人已经设置到了新值,那么我们删除的是别人的锁。

解决:

办法删除锁必须保证原子性,使用redis+Lua脚本完成。

六、分布式锁演进-阶段五 6.1 思想

加锁保证原子性,解锁保证原子性

6.2 问题

锁的自动续期,假设我们业务时间超长,业务还没执行完锁给过期了,所以,我们就要在执行业务期间,给锁自动续期,最简单的操作,就是我把锁的超时时间放长一些。

七、分布式锁最终形态

7.1 压力测试

视频教程

 

关注
打赏
1636984416
查看更多评论
立即登录/注册

微信扫码登录

0.0379s