JAVA常用分布式锁Redisson详解

 更新时间:2025年05月16日 10:41:52   作者:时光呢  
Redisson分布式锁通过Lua脚本的原子性、可重入设计、Watchdog 自动续期和Pub/Sub 通知机制,实现了高效的分布式锁管理,本文给大家介绍JAVA常用分布式锁Redisson详解,感兴趣的朋友一起看看吧

1. 加锁过程

底层命令与数据结构

  • Redis 数据结构:使用 Hash 结构存储锁信息,Key 为锁名称,Field 为客户端唯一标识(如 UUID + 线程ID),Value 为锁的重入次数。
  • Lua 脚本原子性:通过 Lua 脚本在 Redis 中原子性执行加锁逻辑:
 
if (redis.call('exists', KEYS[1]) == 0) then
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then
    redis.call('hincrby', KEYS[1], ARGV[2], 1);
    redis.call('pexpire', KEYS[1], ARGV[1]);
    return nil;
end;
return redis.call('pttl', KEYS[1]);
  • 若锁不存在(exists 为 0)或属于当前线程(hexists 为 1),则增加重入次数并刷新过期时间。
  • 若锁被其他线程占用,返回锁的剩余生存时间(TTL)。

可重入性

同一线程多次获取锁时,重入次数递增,确保不会因多次加锁导致死锁。

2. 锁自动续期(Watchdog 机制)

  • 后台线程续期:加锁成功后,启动一个 Watchdog 线程(看门狗),定期(默认每 10 秒)检查锁是否仍被持有。
  • 续期条件:仅当客户端仍持有锁且业务未完成时,通过 pexpire 命令将锁的过期时间重置为初始值(默认 30 秒)。
  • 崩溃容错:若客户端崩溃,Watchdog 线程停止,锁最终因过期自动释放,避免死锁。

3. 释放锁

释放逻辑

Lua 脚本原子释放

if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then
    return nil;
end;
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) then
    redis.call('pexpire', KEYS[1], ARGV[2]);
    return 0;
else
    redis.call('del', KEYS[1]);
    redis.call('publish', KEYS[2], ARGV[1]);
    return 1;
end;
return nil;
  • 减少重入次数,若次数归零则删除锁,并通过 Pub/Sub 通知等待线程。
  • 确保只有锁的持有者能释放锁,避免误删。

4. 锁竞争与等待

  • 自旋重试:若锁被占用,客户端进入循环,间隔性尝试加锁。
  • Pub/Sub 订阅通知:通过订阅锁释放事件(redisChannel),避免频繁轮询。当锁释放时,Redis 发布消息通知等待线程竞争锁,减少无效请求。

5. 高可用与容错 Redis 部署模式

  • 单节点模式:简单但存在单点故障风险。
  • 主从/集群模式:使用 RedissonMultiLock 实现 RedLock 算法(需多个独立 Redis 节点):
    • 向所有节点顺序申请锁。
    • 当多数节点加锁成功且总耗时小于锁超时时间时,认为加锁成功。
    • 规避主从切换导致锁丢失的问题,但需权衡性能和一致性。

6. 关键注意事项

  • 业务执行时间:业务逻辑必须在锁的过期时间内完成,否则锁可能提前释放。
  • 时钟同步问题:在 RedLock 中,若 Redis 节点间时钟不同步,可能导致锁失效。
  • 网络延迟:极端情况下,锁可能被多个客户端同时持有(需结合业务幂等性处理)。

总结

  • Redisson 分布式锁通过 Lua 脚本的原子性可重入设计Watchdog 自动续期和 Pub/Sub 通知机制,实现了高效的分布式锁管理。其核心优势在于:
  • 避免误删锁(仅持有者可释放)。
  • 支持可重入,适应复杂业务逻辑。
  • 自动续期防止业务未完成时锁过期。
  • 通过 RedLock 支持高可用场景,但需谨慎权衡一致性与性能。

到此这篇关于JAVA常用分布式锁Redisson的文章就介绍到这了,更多相关java分布式锁redisson内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • IDEA一键完成格式化、去除无用引用、编译的操作

    IDEA一键完成格式化、去除无用引用、编译的操作

    这篇文章主要介绍了IDEA一键完成格式化、去除无用引用、编译的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • mybatis 在typeAliases别名时报错的解决

    mybatis 在typeAliases别名时报错的解决

    这篇文章主要介绍了mybatis 在typeAliases别名时报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • spring boot 添加admin监控的方法

    spring boot 添加admin监控的方法

    这篇文章主要介绍了spring boot 添加admin监控的相关知识,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Java性能调优及排查方式

    Java性能调优及排查方式

    这篇文章主要介绍了Java性能调优及排查方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 深入解析java虚拟机

    深入解析java虚拟机

    以下是对java中的虚拟机进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • Java命令行参数解析工具jcommander详解

    Java命令行参数解析工具jcommander详解

    这篇文章主要为大家介绍了Java命令行参数解析工具jcommander命令详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • IDEA下Servlet可能出现404的一些情况

    IDEA下Servlet可能出现404的一些情况

    相信有很多小伙伴遇到报错都不知道怎么处理,今天特地整理了这篇文章,文中对IDEA下Servlet可能出现404的一些情况作了详细的介绍,需要的朋友可以参考下
    2021-06-06
  • java中VO和DTO之间的转换实现

    java中VO和DTO之间的转换实现

    本文主要介绍了java中VO和DTO之间的转换实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • Java枚举类型enum的详解及使用

    Java枚举类型enum的详解及使用

    这篇文章主要介绍了Java枚举类型enum的详解及使用的相关资料,需要的朋友可以参考下
    2017-05-05
  • java javax.annotation.Resource注解的详解

    java javax.annotation.Resource注解的详解

    这篇文章主要介绍了javax.annotation.Resource注解的详解的相关资料,需要的朋友可以参考下
    2016-10-10

最新评论