news 2026/6/23 23:28:47

深入理解 Redisson 分布式锁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解 Redisson 分布式锁

引言

在分布式系统中,多个服务实例往往需要同时访问同一共享资源,例如:

  • 多节点同时修改同一条库存记录
  • 并发执行同一订单处理流程
  • 多实例定时任务同时触发
  • 并发写入同一个数据对象

如果没有分布式锁机制做互斥控制,系统容易出现数据竞争、写冲突、脏写、重复执行等问题。
Redis 因为高性能、单线程执行模型、丰富的原子命令和 Lua 脚本支持,成为当前最主流的分布式锁实现底座。

而 Redisson 作为 Redis 官方推荐的 Java 客户端之一,在锁语义、可重入性、自动续期、原子性保障等方面具有较高的工程完备度。
本文将从工作原理到工程实践全面介绍 Redisson 分布式可重入锁(RLock)。


一、为什么选择 Redisson 实现分布式锁?

如果直接手写 Redis 分布式锁(例如使用SETNX+EXPIRE),会面临大量工程级问题:

问题原因典型风险
SETNX 与 EXPIRE 非原子两条命令获取锁后未设置过期时间 → 死锁
锁删除不安全业务线程崩溃 / 误删删除了别的线程的锁
锁超时后自动释放EX 过期时间不足业务未执行完 → 锁提前过期导致数据错误
不支持可重入SETNX 无法表达线程所有者同一线程再次加锁会造成自阻塞
缺乏自动续期机制自己实现困难业务执行长任务容易导致锁失效

Redisson 提供的 RLock 特性完整解决了上述问题:

  • 可重入语义
  • 自动续期(看门狗机制)
  • 原子加锁 / 解锁(Lua 脚本)
  • 多种锁模式(公平锁、联锁、红锁等)
  • 分布式环境稳定可靠

因此 Redisson 是 Java 体系中工程落地最完善的 Redis 分布式锁方案。


二、Redisson 分布式锁底层原理

1. 锁在 Redis 中的结构

Redisson 使用 Redis 的Hash结构保存锁元数据:

Key: myLock Type: Hash Field: <uuid:threadId> Value: <reentrant count> Expire: 30 seconds (默认锁自动过期时间)

示例:

HSET myLock "e8c0d-...-12:23" 1 EXPIRE myLock 30

这带来几个重要特性:

  • 支持可重入:同一线程再次加锁只需增加次数,不会阻塞
  • 线程级别锁所有权:clientId+threadId 作为唯一标识
  • Redis TTL 控制过期:防止死锁
  • Hash 支持多个 field,可扩展到联锁等高级场景

2. 加锁流程详解

加锁过程使用 Lua 脚本确保原子性:

核心流程(简化逻辑)

  1. 锁不存在→ 设置 Hash(field=当前线程)并设置 TTL
  2. 锁存在但属于当前线程→ 可重入次数+1
  3. 锁存在且不属于当前线程→ 阻塞等待或立即返回失败

所有分支均由 Lua 脚本完成,确保操作原子、不被打断。


三、Spring Boot + Redisson 配置示例

@ConfigurationpublicclassRedissonConfig{@BeanpublicRedissonClientredissonClient(){Configconfig=newConfig();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(0);returnRedisson.create(config);}}

四、加锁与释放锁使用方法

Redisson 提供两类常用加锁方式:

  • lock.lock():阻塞式加锁,自动启动看门狗续期
  • lock.tryLock(...):可设定等待时间与租期,更灵活

1. 使用 lock() —— 自动续期(Watchdog)

@ServicepublicclassLockExampleService{@AutowiredprivateRedissonClientredissonClient;publicvoidtestLock(){RLocklock=redissonClient.getLock("order:lock");try{lock.lock();// 不指定时间 → 自动续期机制生效System.out.println("获取到锁,执行操作...");Thread.sleep(60000);// 业务耗时,看门狗续期保障锁有效}catch(Exceptione){e.printStackTrace();}finally{if(lock.isHeldByCurrentThread()){lock.unlock();}}}}

特点:

  • 默认锁过期时间:30 秒
  • 自动续期(看门狗)每 10 秒刷新过期时间

2. 使用 tryLock()

publicvoidtryLockExample(){RLocklock=redissonClient.getLock("product:lock");try{if(lock.tryLock(5,TimeUnit.SECONDS)){System.out.println("成功获取锁");Thread.sleep(30000);}else{System.out.println("未获取到锁");}}catch(Exceptione){e.printStackTrace();}finally{if(lock.isHeldByCurrentThread()){lock.unlock();}}}

特点:

  • 5 秒内阻塞等待
  • 拿到锁后:启用看门狗自动续期

五、看门狗(Watchdog)机制完整解析

1. 看门狗的工作机制

默认:

  • 检查周期:10 秒
  • 每次续期:将锁 TTL 重置为 30 秒

工作流程:

  1. 定时任务触发
  2. 判断锁是否仍被当前线程持有
  3. 若是 → 调用PEXPIRE myLock 30000
  4. 若线程结束或锁已释放 → 停止续期

2. 为什么需要续期?

如果业务耗时超过锁 TTL(30s),传统分布式锁会提前失效,导致并发问题。
续期确保业务执行再长,也不会中途释放锁。

3. 如何判断“锁属于当前线程”?

通过检查:

HEXISTS myLock <clientId:threadId>

只要当前线程还是 lock 的 owner,就继续续期。


六、Redis 中锁的实时具象表现

加锁后执行:

HGETALL order:lock TTL order:lock

可能看到:

1) "7ab1e9...:23" 2) "1" (integer) 30

随着看门狗执行,TTL 会保持波动但始终在 30 秒附近。


七、锁释放原理(Lua 脚本)

Redisson 使用 Lua 保证解锁的原子性。

  1. 检查锁是否属于当前线程
  2. 若重入次数 > 1 → 次数 -1
  3. 若重入次数为 1 → 删除整个 key
  4. 若锁不属于当前线程 → 不执行任何操作(避免误删)

这个机制保证:“只有锁持有者才能释放锁”。


八、典型问题与常见误区(FAQ)

1. 调用 lock.lock(10, TimeUnit.SECONDS) 会启用看门狗吗?

不会。
指定租期时不启用看门狗,锁达到指定时间后自动释放。


2. 看门狗续期时间可以调整吗?

可以:

config.setLockWatchdogTimeout(45000);// 默认30s

3. Redisson 如何避免死锁?

  • 线程异常退出 → 看门狗停止续期
  • 默认 30s TTL 自动过期
  • 锁结构中包含线程标识,避免误删

4. 可重入锁意味着什么?

同一个线程可以多次获取该锁,不会进入自阻塞:

lock.lock(); lock.lock(); // 重入,计数+1

5. 可否用于分布式事务?

可以用于分布式资源互斥,但不能代替事务。


十、完整业务案例:库存扣减(典型高并发场景)

@ServicepublicclassStockService{@AutowiredprivateRedissonClientredissonClient;publicvoiddeductStock(){RLocklock=redissonClient.getLock("stock:lock");try{lock.lock();// 触发看门狗续期System.out.println("开始扣减库存...");// 模拟扣减操作Thread.sleep(30000);}catch(Exceptione){e.printStackTrace();}finally{if(lock.isHeldByCurrentThread()){lock.unlock();}}}}

适用于:

  • 秒杀减库存
  • 订单去重
  • 并发任务幂等控制
  • 分布式调度系统

总结:Redisson 是 Java 开发中最成熟的 Redis 分布式锁实现

功能点Redisson 是否支持说明
可重入分布式锁Hash 结构记录重入次数
自动续期(看门狗)lock() 自动启用
原子加锁与解锁Lua 脚本保障原子性
死锁自动恢复TTL 到期自动释放
公平锁、联锁、读写锁丰富的分布式同步结构
高性能、可伸缩基于 Redis 单线程执行模型

凭借其完善的锁语义、自动续期机制与 Lua 原子操作设计,Redisson 是 Java 生态中分布式锁的首选方案,适用于中大型业务中的强一致性场景。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/22 11:27:10

Wan2.2-T2V-5B模型提供RESTful API接口文档

Wan2.2-T2V-5B模型提供RESTful API接口文档在短视频内容爆炸式增长的今天&#xff0c;你有没有试过—— 只用一句话&#xff0c;就让AI给你“拍”一段夕阳下气球升空的小动画&#xff1f; &#x1f388;&#x1f305; 不是梦&#xff0c;也不是高端影视特效&#xff0c;而是消费…

作者头像 李华
网站建设 2026/6/23 23:27:35

Wan2.2-T2V-A14B支持多视角同步生成吗?技术瓶颈分析

Wan2.2-T2V-A14B支持多视角同步生成吗&#xff1f;技术瓶颈分析 在影视制作、虚拟现实和智能广告日益依赖AI内容生成的今天&#xff0c;一个关键问题浮出水面&#xff1a;我们能否仅凭一段文字&#xff0c;就让AI从多个摄像机角度一致地“拍摄”同一场戏&#xff1f;&#x1f3…

作者头像 李华
网站建设 2026/6/20 20:50:03

JDK on Windows11

设置环境变量设置环境变量 参考链接&#xff1a; https://cloud.tencent.com/developer/article/2062285

作者头像 李华
网站建设 2026/6/22 17:49:36

Java 之 JFR

参考链接 https://blog.csdn.net/FuncFun/article/details/155570756 https://www.oracle.com/technetwork/cn/java/javaseproducts/mission-control/index.html arthas https://mp.weixin.qq.com/s/5wH1V3dy4XjHNMzbj7S4QA java/jmc.txt: This version of the JDK no lo…

作者头像 李华
网站建设 2026/6/23 19:26:42

Atmosphere-NX 2168-0002错误诊断与修复终极指南

Atmosphere-NX 2168-0002错误诊断与修复终极指南 【免费下载链接】Atmosphere Atmosphre is a work-in-progress customized firmware for the Nintendo Switch. 项目地址: https://gitcode.com/GitHub_Trending/at/Atmosphere 在Atmosphere自定义固件的使用过程中&…

作者头像 李华
网站建设 2026/6/23 21:16:16

三步实现医疗级数据加密,C#开发者必须掌握的安全技能

第一章&#xff1a;医疗系统中数据加密的重要性 在现代医疗信息系统中&#xff0c;患者隐私和数据安全已成为核心关注点。随着电子健康记录&#xff08;EHR&#xff09;的普及&#xff0c;大量敏感信息如病史、诊断结果和身份信息被数字化存储与传输&#xff0c;一旦泄露可能造…

作者头像 李华