分布式锁 - redis实现方案

2021-06-13  本文已影响0人  乌木山

在普通的单机程序中,我们为了避免资源竞争,通常会使用synchronizelock 等方式进行加锁防止并发问题。不过在分布式系统中,请求是并发的在多台机器上执行,这时候就需要使用分布式锁来防止资源竞争问题。

提到分布式锁,我们最常见的方案就是基于redis实现,本文将依次解释

redis分布式锁

我们知道redis由于其单线程的模式,可以保证各命令按顺序、原子的执行。

Redis的分布式锁主要使用了setnx命令。

一般来说,为了防止发生由于服务问题导致解锁命令未执行而造成锁一致无法被释放(死锁)的情况。会在加锁时同时使用expire key timeout命令设置一个默认的超时时间。由于setnxexpire 是两个命令,为了保证原子性,可以通过lua脚本的方式进行执行。

上述方案已经可以实现一个基本的分布式锁,但是还是会有一些特殊的场景及问题需要我们去关注并解决。

分布式锁特殊场景

错误释放锁

这种场景,可以通过每个线程设置value都是与之唯一对应的value来解决(例如UUID)。然后在del的时候做一个value校验来防止误删除。

守护线程续约

注意守护进程也需要进行value校验,防止错误的续约操作。当主线程执行完业务后,同时关闭掉守护线程即可。(如果主线程意外关闭了,守护线程也会自动关闭)

其他问题

除了上述问题,redis本身在主从切换、脑裂问题等极端情况导致的数据不一致问题,也会导致分布式锁的错误。

参考资料

https://xiaomi-info.github.io/2019/12/17/redis-distributed-lock/

上一篇 下一篇

猜你喜欢

热点阅读