Redis实现分布式锁注意事项

0 阅读3分钟

一、基本认识

  1. redis不同的逻辑数据库的Key空间是隔离的,而不是资源或安全上的隔离。在生产环境中建议优先使用独立的Redis实例来实现业务隔离。

  2. redis分布式锁的安全边界在哪里? Redis是内存数据库,所以天然面临一个核心矛盾: 内存中的数据,进程挂了怎么办?Redis在部署拓扑下并不是强一致性存储

SET lock_key unique_value NX PX 30000

二、RDB/AOF思想与限制

RDB/AOF,本质上是围绕这个矛盾设计的两种“持久化策略控制手段”。

RDB(Redis Database):解决”冷备份+全量恢复“问题,本质是某一时刻内存数据的完整快照。RDB是通过快照的方式工作的。它会按照配置的策略,将当前内存中的数据完整地序列化成一个二进制文件(默认文件名为dump.rdb).

解决的是:我至少能恢复到某个时间点。

代价:

  • 丢失最后一次快照之后的数据
  • fork有内存放大风险
  • 不适合高频写场景的强一致需求

AOF(Append Only File):解决数据丢失窗口太大的问题。把内存操作日志化。

三、使用分布式锁需要考虑的场景

  1. 锁过期未及时续约,导致锁提前释放
  • 风险:任务还在执行,锁已经因为未续期而被其他线程抢占。
  • 应对:引入 看门狗机制(自动续期),如Redisson的lock机制。
  1. 业务执行时间难估,导致锁时间设置不合理
  • 风险:设置时间过短导致任务未执行完锁就释放;设置太长影响并发。
  • 应对:设置锁过期时间 > 正常业务最长耗时;结合 自动续期机制
  1. 锁未过期,业务异常退出导致死锁
  • 风险:持锁线程/节点宕机,锁未释放,阻塞后续逻辑。
  • 应对:始终设置合理过期时间,避免永久锁;
  1. 主从复制延迟,导致锁实效或重入错误
  • 风险:客户端向主节点写入锁后,主节点宕机,副本未同步该key,锁信息丢失。
  • 应对:采用 RedLock(多主一致加锁) 模型,或部署支持强一致性的Redis架构(如Redis哨兵集群 + Redis副本复制确认min-replicas-to-write)。 我司内为哨兵模式部署,一主二从,强一致性成本过高,且发生该问题概率很低。因此针对重要业务场景,建议引入锁获取/释放监控日志与告警,便于问题排查和补偿。
  1. 锁被误释放(释放了他人的锁)
  • 风险:由于使用统一Key,没有区分线程/节点身份,导致释放了其他线程/节点加的锁。
  • 应对:写入锁时附带唯一标识(UUID或线程ID),释放锁时校验身份。同时不同应用连接不同的redis逻辑数据库,避免碰撞风险。
  1. 锁粒度设计不合理
  • 风险:锁Key设计过粗,限制并发;过细则不能控制互斥。
  • 应对:结合业务特性,采用合适的锁粒度策略
  1. 锁重入不可控
  • 风险:需要在同一线程/事务中多次获取锁,常规实现会失败。
  • 应对:引入 可重入锁封装,如使用Redisson支持的ReentrantLock。

四、金融业务场景下,分布式锁的选型思路

如果涉及:

  • 核心账务扣款
  • 余额冻结
  • 分布式事务协同

建议:

  • DB行锁
  • 乐观锁版本号
  • 给予数据库唯一约束实现幂等

因为Redis实现分布式锁:

  1. 在主从架构下一定存在锁丢失风险
  2. 不要把Redis锁当成强一致协调机制
  3. Redis锁是“工程折中方案”,不是分布式共识。