Redis 分布式锁续期:锁还在,不代表业务安全

发布时间:2026/7/5 14:47:02

Redis 分布式锁续期:锁还在,不代表业务安全 Redis 分布式锁续期锁还在不代表业务安全一、分布式锁最怕误以为安全Redis 分布式锁常用于防重复任务、定时调度、库存扣减和资源互斥。加锁成功后很多代码就放心执行业务。但业务执行时间如果超过锁过期时间或者续期线程异常另一个实例可能拿到锁并发执行。锁还在不代表业务安全。锁的生命周期必须和业务状态一起设计。二、锁要有唯一标识flowchart TD A[请求加锁] -- B[写入锁值] B -- C[执行业务] C -- D[校验锁值] D -- E[释放锁]释放锁时必须校验锁值不能只按 key 删除。否则 A 的锁过期后 B 获得锁A 结束时可能把 B 的锁删掉。if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end锁值通常使用 requestId 或随机 token。三、续期要看业务边界如果业务可能超过锁 TTL可以做 watchdog 续期。但续期不是万能药。续期线程卡住、进程 STW、网络抖动都可能导致锁失效。lock_policy: ttl_seconds: 30 renew_interval_seconds: 10 max_hold_seconds: 300要设置最大持有时间避免业务卡死后锁一直续。四、业务要能防重复分布式锁只能降低并发概率不能代替业务幂等。关键动作仍要有唯一约束、状态机或版本号兜底。CREATE UNIQUE INDEX uk_job_day ON settlement_job(biz_date);如果锁失效导致重复执行数据库约束至少能挡住结果污染。最后锁要有监控。加锁失败率、锁持有时间、续期失败次数、超时释放次数都能反映系统是否接近危险边界。还要区分锁失败和业务失败。拿不到锁不一定是错误可能只是另一个实例正在处理续期失败则更危险说明当前实例可能已经失去互斥保障。日志级别和告警策略要分开。lock_metrics: acquire_failed: info_or_warn renew_failed: alert hold_time_p99: monitored force_release_count: alert如果业务跨机房部署还要谨慎使用单 Redis 锁。网络分区、主从切换、复制延迟都会影响锁语义。关键资金、库存或结算场景不能只靠缓存锁兜底。最后锁粒度也要设计。锁太粗影响吞吐锁太细容易漏互斥。按业务主键、租户、日期还是资源 ID 加锁需要和并发冲突模型一致。锁超时后的处理也要明确。业务执行到一半发现续期失败不能假装什么都没发生继续写结果。可以设置中断标志进入补偿流程或者在最终提交前再次校验业务版本。if (!lockService.stillOwner(lockKey, token)) { throw new LockLostException(lock ownership lost); }对于定时任务锁失效后要避免两个实例同时推进游标。游标更新应使用乐观锁或唯一版本号确保只有一个实例能提交进度。还要给锁操作设置超时。Redis 调用本身如果卡住业务线程不能无限等待。加锁、续期、释放都应该有短超时和失败处理。最后评审分布式锁代码时要把“锁保护了什么资源”写清楚。看不清保护对象的锁通常也很难证明它正确。五、总结Redis 分布式锁续期要校验锁值、设置 TTL 和最大持有时间并用业务幂等兜底。锁还在不代表业务安全。真正安全的是锁、状态和约束一起工作。

相关新闻