决战圣地玛丽乔亚Day50--Redis实现分布式锁
分布式锁的最简单版本: setnx key value
set key value 命令是对key设置值的命令,不管key是否存在值都会设置进去。
setnx key value命令对key进行值的设置前进行非空判断,如果key有值返回0,如果key为空就设置返回1.
在setnx失败后会循环等待锁的释放:
缺点:没有对超时进行限制,如果在delete之前进行宕机,那么锁永远不会释放出去,那么就一直超时等待。
升级版本:给key设置一个超时时间
set key value ex 多少秒 nx
nx 表示该set命令具备setnx的特性。
如:set key eminent ex 60 nx 对key eminent设置60s过期时间,具备setnx特性
但是会出现一个问题,设置的60s内,如果业务流程较长的情况下,超出了60s。线程A释放key后,线程B获取了分布式锁执行任务。当线程A业务流程走完后删除锁
删除的是线程B的锁。锁的获取和删除都是通过锁的名称来进行分辨,所以在此基础上,我们需要加一个线程判断:
我们可以把set key eminent ex 60 nx 命令的锁的名称设置为当前线程的唯一标识,这样我们在删除的时候,对锁的名称进行一次判断即可解决这个问题。
业务逻辑执行超时的情况下:
新的问题是:
判断锁是否是当前线程和释放锁的操作不是原子性操作。就可能会导致,判断完确定释放后进行卡顿,卡顿期间线程B获取锁,恢复卡顿后,删除的是别的线程的锁。
最终版本:通过Lua脚本保证判断线程和执行操作的原子性。
我们可以通过Lua脚本在加锁的时候解决不可重入的问题。
在Lua脚本中先判断锁(key)是否存在,如果存在则再判断持有这把锁的线程是否是当前线程,如果不是则加锁失败,否则当前线程再次持有这把锁,并把锁的重入次数+1。在释放锁时,也是先判断持有锁的线程是否是当前线程,如果是则将锁的重入次数-1,直至重入次数减至0,即可删除该锁(key)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南