Redis 如何实现分布式锁-单机 Redis

naive 版

加锁:

SETNX ${lockName} ${value}	# set if not exist

如果不存在则插入成功,返回 1,加锁成功;否则返回 0,加锁失败

解锁:

DEL ${lockName}

问题1

2 个线程 A、B,线程 A 拿到了锁后,宕机了怎么办?谁来释放锁?

解决:使用自动过期机制:

加锁:

SET ${lockName} ${value} EX 10 NX	# atomic opreation

解锁:

DEL ${lockName}

问题2

在这里插入图片描述

t0 时刻实例1获取到锁,t3 时刻被自动释放(国企),同时实例2获取到锁,t4 时刻实例1再次释放(实例2的锁),实例3又获取到了锁,造成了数据混乱

解决:设置 value 为当前实例线程 id,在解锁时做判断

加锁:

SET ${localName} ${threadId} EX 10 NX

解锁(使用 lua 脚本实现原子性):

current_value = get ${lockName}
if ${threadId} == current_value then
	DEL ${lockName}

问题3

在这里插入图片描述

锁被自动释放的问题仍然存在

启动一个异步线程(WatchDog),获取到锁成功后启动异步线程,每隔 x 秒对当前锁续期 y 秒,直到锁被释放停止

至此,单机版的 Redis 分布式锁就得到了成功实现

上一篇:如果项目在上线后才发现Bug怎么办?-感谢每一个认真阅读我文章的人!!!


下一篇:sentinel-1.8.7与nacos-2.3.0实现动态规则配置、双向同步