zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

基于redis实现分布式锁遇到的一个坑

Redis分布式分布式 实现 一个 基于 遇到
2023-09-27 14:23:02 时间
背景

之前旧代码中使用redis的incr来实现分布式锁。
逻辑大概是线上诸多线程去获取inrc一个key,第一个成功的则得到返回值1。其他线程如果inc这个变量则返回2,3,4,5…
成功返回的线程,然后再对这个key设值一个过期时间30秒。代码已经在线上跑了几个月了,没啥毛病。

遇到问题

这个问题是在测试环境遇到的,什么情况呢?就是没有线程可以成功获取这个key了,换句话说,就是这个key永远不等于1了。
查询了下redis,发现已经增加到几万了,用ttl看返回的是-1,也就是说,生命周期是永久了。

排查

对代码逻辑仔细排查,未发现不妥的逻辑。
后来,想了想,只有一种情况会出现这样的情况,那就是第一个成功incr key的线程,在进行incr后,在没来得及设值过期的时候,线程就挂了,可能是程序崩了,可能是被测试同学在启动工程的时候,停掉了,或者部署工程其他分支等。反正就是挂了。
所以这一点就违背了分布式锁的一个条件(无死锁)。

分布式锁需要具备哪些条件?
互斥性:在任意一个时刻,只有一个客户端持有锁。
无死锁:即便持有锁的客户端崩溃或者其他意外事件,锁仍然可以被获取。
容错:只要大部分Redis节点都活着,客户端就可以获取和释放锁

验证想法

在redis del 掉这个key