Redis 分布式锁与 Redisson 看门狗

发布时间:2026/10/19 18:20:12
Redis 分布式锁与 Redisson 看门狗 一句话Redis 分布式锁的核心是用SET key value NX EX seconds原子加锁用唯一 value 标识锁持有者用 Lua 脚本原子释放锁生产环境常用 Redisson因为它支持可重入锁和看门狗自动续期。1. 分布式锁解决什么问题单机synchronized或ReentrantLock只能锁住一个 JVM 内部的线程。在多实例部署时应用实例 A 应用实例 B 应用实例 C ↓ 同时处理同一个订单 / 同一个库存 / 同一个缓存重建任务这时本地锁无法跨机器生效需要一个所有实例都能访问的公共锁服务。Redis 就经常被用来实现分布式锁。2. 错误写法SETNX EXPIRESETNX lock:order1EXPIRE lock:order30问题是两条命令不是原子操作线程 A 执行 SETNX 成功 ↓ 还没来得及执行 EXPIRE ↓ 服务宕机 ↓ 锁没有过期时间永远不释放 ↓ 其他线程再也拿不到锁所以不能把加锁和设置过期时间拆开。3. 正确加锁SET NX EXSET lock:order uniqueValue NX EX30含义SET设置 key NX只有 key 不存在时才设置保证只有一个线程抢锁成功 EX 30设置 30 秒过期时间防止服务宕机后死锁 uniqueValue锁持有者唯一标识例如 UUID 线程 ID这是一条原子命令加锁和设置过期时间同时完成。4. 为什么 value 不能写固定值错误示例SET lock:order1NX EX30如果 value 固定释放锁时无法判断这把锁是不是自己的。典型误删场景线程 A 获取锁过期时间 30 秒 线程 A 业务执行太慢超过 30 秒 锁自动过期 线程 B 获取同一把锁 线程 A 执行完直接 DEL lock:order 结果线程 A 把线程 B 的锁删了所以 value 必须是唯一标识释放锁前要先判断 value 是否等于当前线程持有的值。5. 正确释放锁Lua 原子校验 删除释放锁不能简单DEL key而要ifredis.call(GET,KEYS[1])ARGV[1]thenreturnredis.call(DEL,KEYS[1])elsereturn0end为什么必须用 Lua如果先 GET 判断再 DEL 删除是两条命令。 中间锁可能过期并被其他线程重新获取。 此时原线程再 DEL就可能误删别人的锁。 Lua 脚本在 Redis 中作为一个整体执行中间不会插入其他命令 所以能保证“判断身份 删除锁”的原子性。6. Redis 分布式锁仍然有什么问题过期时间不好设置设置太短 业务没执行完锁就过期其他线程进入临界区 设置太长 服务真的宕机其他线程要等很久才能拿锁不适合所有强一致场景Redis 分布式锁适合防重复执行、缓存重建、普通业务互斥。对于金融级强一致仍要结合数据库事务、唯一索引、乐观锁或更强的一致性组件。7. Redisson 做了什么Redisson 是 Redis 官方推荐之外很常用的 Java 客户端封装提供了更完整的分布式锁能力① 可重入锁 同一个线程重复加锁不会死锁 内部记录重入次数 ② 看门狗自动续期 业务没执行完时自动延长锁过期时间 ③ Lua 脚本释放锁 自动做 value 校验避免误删锁 ④ 更接近 Java Lock 的使用方式 RLock lock redissonClient.getLock(lock:order)8. 看门狗机制看门狗解决的是“锁过期时间不好设置”的问题。默认锁过期时间30 秒 续期间隔约 10 秒检查一次 如果业务线程还持有锁把过期时间续回 30 秒 业务执行完 unlock释放锁并停止续期 服务宕机看门狗线程也停止锁最多 30 秒后自然过期流程lock.lock() ↓ Redisson 加锁成功默认 TTL 30s ↓ 业务线程还活着并持有锁 ↓ 看门狗每隔约 10s 续期一次 ↓ 业务执行完 unlock() ↓ 删除锁停止续期注意通常只有加锁时​不手动指定 leaseTime​看门狗才会自动续期。lock.lock();// 有看门狗自动续期lock.lock(10,TimeUnit.SECONDS);// 通常按指定时间过期不走自动续期9. 分布式锁使用注意事项① 加锁要设置过期时间避免死锁 ② value 要唯一避免误删别人锁 ③ 释放锁要用 Lua 原子判断 删除 ④ 锁粒度不要太粗否则并发能力下降 ⑤ 锁内代码要尽量短不要做慢 SQL 或远程长调用 ⑥ finally 中释放锁避免异常导致锁不释放典型代码结构RLocklockredissonClient.getLock(lock:order:orderId);lock.lock();try{// 查询状态、校验、执行业务更新}finally{lock.unlock();}10. 面试高频追问SET NX EX 能保证绝对安全吗它能保证单 Redis 实例上的加锁原子性和自动过期 但不能解决所有分布式一致性问题。 如果 Redis 主从发生故障切换锁还没同步到从节点就切主 可能出现多个客户端都认为自己拿到锁的情况。 普通业务通常可以接受强一致场景要结合数据库约束或更强一致性的方案。Redisson 看门狗会不会导致锁永远不释放正常不会。业务线程还活着并持有锁时才续期unlock 后停止续期。 如果服务宕机看门狗线程也没了锁会在默认 30 秒后过期。面试回答模板“Redis 分布式锁一般用 SET key value NX EX seconds 实现。 NX 保证 key 不存在时才能加锁EX 设置过期时间防止服务宕机后死锁。 这条命令是原子的不能拆成 SETNX 和 EXPIRE。 value 不能写固定值要用 UUID 加线程 ID 这类唯一标识。释放锁时不能直接 DEL 要用 Lua 脚本先判断 value 是不是自己的再删除避免锁过期后误删别人的锁。 生产环境我会优先用 Redisson。它支持可重入锁和看门狗机制如果没有手动指定 leaseTime默认锁 30 秒过期看门狗大约每 10 秒续期一次。业务执行完 unlock 后停止续期服务宕机后看门狗停止锁最多 30 秒后自然释放。”

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询