分布式锁-redis

分布式锁的使用场景:

比如公司为了实现服务一直可用,会部署多个实例,这样就可以一台一台机器的这样部署,其中一台部署着,另外一台还在运行,那么服务就是可用的,不会说一直处于服务不可用的状态。当处于这样场景的时候,如果你服务中有个定时任务的话,那么到点的时候,会触发多个实例的定时任务,也就是同一个时刻会执行多次定时任务里面的逻辑。如果任务的逻辑是不允许重复执行,那么这个时候就要加分布式锁,就是其中一台机器拿到处理的锁后,其他机器拿不到,就不进入逻辑处理的部分。

在redis中,实现分布锁的指令为: 

SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写,不存在就set,同时返回true,存在的话就直接返回false。那么这样就可以实现只用一台机器拿到锁的逻辑。

 

主机x 执行 setnx  比如: setnx  lock  "true",返回true,进入定时任务的处理逻辑

主机y就无法设置成功,直接返回false, 那么不进入处理逻辑

处理逻辑

主机x执行del操作,完成处理逻辑

很明显这里可以会出现死锁的问题,就是当处理逻辑出现异常(同时没有做try...catch处理的时候),或者当处理逻辑在处理的时候,因为新上线的代码要部署时,刚好部署到定时任务的代码的服务,那么就会出现del操作不成功的情况。

 

主机x 执行 setnx  比如: setnx  lock  "true",返回true,

继续对锁进行过期处理: expire lock 60  (60秒过期),进入定时任务的处理逻辑

主机y就无法设置成功,直接返回false, 那么不进入处理逻辑

处理逻辑

主机x执行del操作,完成处理逻辑

这种情况会比较好一点,如果处理逻辑或者重新部署服务的已经跑到处理逻辑的时候,因为有个过期时间,就不会死锁。但是如果在setnx之后,expire的逻辑没有设置就出异常了,那么也是会引起死锁的。

 

 

主机x 执行 setnx和expire的原子性操作,不过要在redis2.8之后才支持,比如: set lock "true" ex 60 nx ,返回true,

进入定时任务的处理逻辑

主机y就无法设置成功,直接返回false, 那么不进入处理逻辑

处理逻辑

主机x执行del操作,完成处理逻辑

这种对于单实例的redis来说就不会出现说死锁的问题,因为有过期时间的key,那么时间到期后,下一个定时任务周期一来,就能设置成功。但是对于多个redis集群的情况就可能会出现死锁了(比如redis主从逻辑,当给主redis设置了锁后,还没来得急同步到从redis,此时主redis就挂机了,那么从的升为主redis,那么这个锁就没加成功,其他其他机器就可以也获取的锁进入业务逻辑,但是这种情况基本可以忽略,就不扩展了)。

 

上述的场景中,还有一种就是当业务的时间比较长的时候,就是当锁已经过期了,但是业务还是没有处理完,然后就定时任务又来了,就相当于两个一样逻辑的任务在进行。这种情况可以使用redis客户端redisson,给锁自动续期。

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读