当前位置: 首页 > news >正文

Redisson和Redis实现分布式锁的对比

一、原子性保障

特性

SETNX 实现

Redisson 实现

加锁操作

需组合 SETNX

+ EXPIRE

命令,需通过 Lua 脚本保证原子性(否则存在竞态条件)。

内置原子性 Lua 脚本,封装加锁、续期、释放锁的全流程,避免非原子操作风险。

锁释放

需手动校验锁标识(如 UUID),否则可能误删其他线程的锁。

自动校验锁持有者身份,仅允许持有者释放锁,避免误删。

示例对比

  • SETNX 手动实现
// 非原子操作,需分步执行
String uuid = UUID.randomUUID().toString();
jedis.setnx(lockKey, uuid);  // 加锁
jedis.expire(lockKey, 30);   // 设置超时(非原子)
  • Redisson 实现
RLock lock = redisson.getLock(lockKey);
lock.lock();  // 原子性操作,内置 Lua 脚本

二、自动续期(看门狗机制)

特性

SETNX 实现

Redisson 实现

续期逻辑

需手动实现后台线程定期续期,代码复杂度高,易遗漏。

内置看门狗线程,自动续期(默认 30 秒续期至 30 秒),动态调整续期间隔。

适用场景

短时操作(如秒杀库存),长事务需自行优化。

长事务(>30 秒)场景,自动续期保障锁有效性。

原理
Redisson 通过后台线程定期检查锁的剩余存活时间,若小于阈值(如 10 秒),则通过 EXPIRE 命令续期,避免业务未完成导致锁提前失效。


三、可重入性支持

特性

SETNX 实现

Redisson 实现

可重入性

需自行维护线程标识和计数器,实现复杂。

默认支持可重入锁,通过 Hash 结构记录线程 ID 和重入次数,支持递归调用。

代码复杂度

需手动处理重入逻辑,易出错。

透明化处理,开发者无需关注底层细节。

数据结构对比

  • SETNX:需自行维护类似 lockKey -> {threadId: count} 的 Hash 结构。
  • Redisson:自动通过 Lua 脚本管理 Hash 结构,重入时直接增加计数器。

四、高可用与容灾

特性

SETNX 实现

Redisson 实现

单点故障

单节点 Redis 存在单点故障风险。

支持 RedLock 算法(多节点集群)和哨兵模式,提升容灾能力。

集群支持

需自行实现多节点锁同步(如 RedLock),代码复杂度高。

原生支持 RedLock 和哨兵模式,简化集群部署。

RedLock 原理
在多个独立 Redis 实例上尝试加锁,需超过半数节点成功才视为加锁成功,避免单点故障。


五、开发体验与功能扩展

特性

SETNX 实现

Redisson 实现

API 丰富度

需手动实现阻塞锁、尝试锁、公平锁等逻辑,开发成本高。

提供 RLock

接口和丰富 API(如 tryLock

lockInterruptibly

、公平锁)。

功能扩展

需自行实现联锁(MultiLock)、读写锁等复杂场景。

原生支持联锁、红锁(RedLock)、公平锁等企业级功能。

示例
Redisson 的公平锁通过有序集合(Sorted Set)维护等待队列,按请求顺序分配锁,避免饥饿现象。


六、性能对比

场景

SETNX 实现

Redisson 实现

单节点模式

TPS 约 35,000 次/秒(轻量级操作)。

TPS 约 28,000 次/秒(因 Hash 操作和后台线程开销)。

集群模式

需自行实现高可用逻辑,性能波动大。

原生支持集群模式,动态扩缩容,性能更稳定。


七、总结:适用场景建议

  1. 选择 SETNX 的情况
    • 业务简单且对性能敏感(如秒杀库存)。
    • 开发者熟悉 Redis 原生命令,愿意自行处理锁续期、可重入等逻辑。
  1. 选择 Redisson 的情况
    • 涉及长事务、可重入性、高可用需求。
    • 需要快速实现复杂锁类型(如公平锁、联锁)。
    • 企业级项目追求开发效率和代码健壮性。

八、扩展思考

  • 锁粒度控制:Redisson 支持细粒度锁(如 Hash 结构中的字段级锁),而 SETNX 通常只能实现粗粒度锁。
  • 监控与调试:Redisson 提供锁状态监控接口,便于排查锁竞争和性能瓶颈。
  • 社区生态:Redisson 作为 Redis 官方推荐客户端,与 Spring、Dubbo 等框架集成更紧密。


http://www.dtcms.com/a/361768.html

相关文章:

  • 【免费数据】2019年我国36个主要城市的高分辨率城市空地分布矢量数据
  • 【2025ICCV】
  • FOUPK3云服务平台旗下产品
  • Python 实战:内网渗透中的信息收集自动化脚本(7)
  • GD32入门到实战24--RTC实时时钟
  • 恶意软件概念学习
  • 【游戏开发】Houdini相较于Blender在游戏开发上有什么优劣势?我该怎么选择开发工具?
  • 【Java】Redis(中间件)
  • 订单后台管理系统-day07菜品模块
  • 域名备案后不解析可以吗
  • 五、导入现有模型
  • Docker基本介绍
  • 面试记录8 Linux/c++中级开发工程师(智能座舱)
  • 六大关键步骤:用MES系统重构生产计划管理闭环
  • Linux开发必备:yum/vim/gcc/make全攻略
  • 如何使用 JMeter 进行接口测试。
  • Java 常见异常系列:NumberFormatException 数字格式异常
  • ROS1系列学习笔记之ROS的调用,示例为激光雷达N10P的运行(含常见问题与踩坑解答)
  • 数据结构:计数排序 (Counting Sort)
  • 逻辑门编程(一)——与或非门
  • 接口响应慢 问题排查指南
  • MongoDB 内存管理:WiredTiger 引擎原理与配置优化
  • GraalVM Native Image:让 Java 程序秒启动
  • 植物中lncRNA鉴定和注释流程,代码(包含Identified,Classification,WGCNA.....)
  • shell编程 函数、数组与正则表达式
  • 预处理——嵌入式学习笔记
  • day06——类型转换、赋值、深浅拷贝、可变和不可变类型
  • 009=基于YOLO12与PaddleOCR的车牌识别系统(Python+PySide6界面+训练代码)
  • C++运行时类型识别
  • k8s知识点汇总2