为了账号安全,请及时绑定邮箱和手机立即绑定

Redis分布式锁超时 导致多个任务获取锁的解决思路?

Redis分布式锁超时 导致多个任务获取锁的解决思路?

MMMHUHU 2019-03-25 11:25:58
问题描述使用Redis集群分布式锁, 并利用超时自动释放(某些原因线程死掉后依赖超时) 但是 如果一个服务a的线程A获取了LockC锁,由于网络原因, 获取锁后断网(线程A没挂,也许只是阻塞了,也没处理完) Redis集群到了超时时间LockC被释放了 此时另一个服务b的线程B获取了LockC锁,且往下执行(假设B线程跟A处理的结果有交叉) 但过了一会, 服务a的网络又好了, 线程又继续执行,就出现了不一致问题 请问有什么思路么?
查看完整描述

2 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

如果数据源处不进行修改(比如增加版本号控制),那么没有任何解决方案。
因为不光网络问题。gc的stw阶段,或者page fault导致的阻塞你也是没办法控制的。即使随时随地去判断锁的状态,你仍然没办法去确定判断完后,是否会进入一次gc或者page fault。
redis锁的问题在于,超时后会自动释放锁。所以可以考虑使用zk的锁,zk是基于session的锁,不会有超时时间,只会在session关闭后释放(但是仍然无法防止长时间gc导致zk检测不到心跳导致的过期)。
总结来说就是,如果只是考虑到效率,而允许某些情况下同时存在两个进程获取锁,那么使用redis锁没有任何问题;如果需要正确性,那么redis的锁不是一个很好的实现,zk的锁是一个更好的思路,但是仍然存在问题,更好的方式是,数据源处进行修改,增加版本控制或者某些程度上事务(ACID)的支持(这就引入了既然数据源处已经支持了锁,我们还需要分布式锁干什么这个问题,你可以思考一下这里);如果对效率不是那么看中,比如一些异步处理,那么甚至可以用队列+单线程消费者去处理,天然的免锁。

查看完整回答
1 反对 回复 2019-03-25
?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

在 a 碰到网络异常等情况并恢复后可以判断自己是否还是锁的持有者,如果不是则抛出异常不继续执行。
同理在是否锁的时候也需要关注释放异常的情况。

查看完整回答
反对 回复 2019-03-25
  • 2 回答
  • 0 关注
  • 1890 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号