redis分布式锁在主从切换时丢失的根本原因是锁仅写入主节点且异步复制未完成,导致新主节点无锁;解决需架构升级:redlock多节点共识、强化主从同步(min-slaves配置)、换用zookeeper/etcd强一致性服务,或采用redisson等成熟客户端封装。

Redis 分布式锁在主从切换时丢失,根本原因是锁只写在主节点,而异步复制没来得及同步到从节点,主节点宕机后新主节点上没有该锁,其他客户端就能重复加锁。这不是配置问题,而是单点锁模型在高可用场景下的固有缺陷。要真正避免锁丢失,需跳出“依赖一个 Redis 实例”的思路,从架构层面升级方案。
用 RedLock 算法实现多节点共识
RedLock 的核心是不把锁押在单个 Redis 实例上,而是向多个相互独立的 Redis 主节点(建议 5 个)并发申请锁:
- 按顺序尝试在每个节点执行
SET key value NX PX 30000,value 必须是全局唯一标识(如 UUID) - 设置较短的网络超时(比如 50ms),避免卡死在一个故障节点
- 统计成功加锁的节点数,只有超过半数(如 5 个中 ≥3 个)且总耗时小于锁过期时间,才算获取成功
- 最终锁的有效期 = 原设定时间 − 实际获取耗时,防止因网络延迟导致锁提前失效
这样即使某个节点崩溃重启、或发生主从切换,只要多数节点仍正常,锁的持有状态就可被共识确认,不会凭空消失。
强化主从同步策略(辅助手段)
若暂时无法改造为 RedLock,可在主从架构下收紧 Redis 配置,降低锁未同步即切换的概率:
- 启用
min-slaves-to-write 1:强制主节点至少有一个从节点在线才接受写请求 - 设置
min-slaves-max-lag 10(单位秒):要求从节点延迟不能超过 10 秒,否则主节点拒绝写入 - 配合持久化(如 AOF + everysec)和 Sentinel 故障转移超时调优(
down-after-milliseconds不宜过短)
注意:这只是“降低概率”,不能彻底杜绝锁丢失,尤其在网络分区(脑裂)时依然可能失效。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
换用强一致性协调服务(终极方案)
当业务对锁的严格互斥性要求极高(如金融交易、库存扣减),推荐直接放弃 Redis,改用 ZooKeeper 或 etcd:
- ZooKeeper 利用 ZAB 协议保证所有节点数据强一致,临时顺序节点天然支持锁的创建、释放与自动清理
- 主节点切换过程中,锁信息不会丢失,客户端连接中断后会自动重连并感知锁状态
- 无需手动处理锁续期、value 校验、超时判断等细节,语义更清晰可靠
Redis 本质是缓存系统,不是分布式协调服务;ZooKeeper 才是为这类场景设计的。
使用成熟客户端封装(务实选择)
实际项目中,不建议手写 RedLock 或 ZooKeeper 锁逻辑。可直接采用:
-
Redisson:内置 RedLock 支持(
RLock lock = redisson.getMultiLock(...)),也提供 ZooKeeper 模式选项,自动处理重试、续约、异常恢复 - Lettuce:支持 Redis Cluster 和 Sentinel,配合自定义 Lua 脚本也能构建较健壮的锁流程
重点不是“怎么写”,而是“谁来保证正确性”——交给经过大规模验证的库比自己拼凑更稳妥。










