You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sidekiq/Ruby On Rails使用Redis Redlock锁偶发无法正确锁定问题

问题原因分析
  • 日志埋点时序错误:你的代码先执行puts("locking! #{task_id}")打印加锁日志,再调用lock_manager.lock申请锁。即使锁申请失败也会先打印加锁日志,仅从你提供的日志无法直接判定两个任务都成功拿到了锁,这是最容易引发误判的点。
  • Redlock客户端初始化逻辑错误:你每次执行perform方法都会重新初始化Redlock::Client实例,Redlock算法依赖客户端与Redis节点的时钟偏移校准值,每次新建实例都会重新计算偏移,在两个请求间隔仅1ms的极端场景下,不同实例的偏移计算误差可能导致锁的有效性校验逻辑判断异常,出现两个请求都判定自己持有锁的问题。正确做法是将Redlock客户端全局初始化一次,作为单例复用即可。
  • 单节点场景下Redlock特性不适配:Redlock本身是为多Redis节点的分布式场景设计的,单节点使用时锁安全性和普通SETNX加锁没有区别,同时Redlock默认开启3次锁申请重试,重试间隔带随机抖动,极端场景下可能出现前一个任务刚释放锁,后一个重试请求刚好拿到锁的情况,让你误以为两个任务并发持有锁。
  • 锁TTL配置的潜在风险:你设置的锁TTL是6分钟,如果任务实际执行时间超过6分钟,锁会自动过期释放,后续请求也能拿到锁,出现并发执行的问题,建议根据任务实际最大执行时长合理设置TTL,或者添加锁续期逻辑。
  • 潜在的变量引用错误:你的方法入参是task_id和task_type,但执行任务时调用的是Services::ExecTasks::Run.call task.id,如果此处task是未定义变量,会抛出异常直接触发ensure分支的解锁逻辑,如果你没有捕获异常日志,会误以为任务是正常执行完成的。

内容的提问来源于stack exchange,提问作者Amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:18:03