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

Redisson 介绍

Redisson 介绍

Redisson 是一个高级的 Redis 客户端,基于 Netty 框架实现,提供了丰富的分布式对象和服务。它不仅简化了 Redis 的使用,还提供了分布式锁、集合、映射等高级功能。

Redisson 核心特性

1. 基础功能

  • 连接池管理:自动管理连接,支持哨兵、集群模式
  • 异步支持:提供同步、异步、响应式三种 API
  • 序列化:支持多种序列化方式(JSON、Kryo、FST 等)
  • 重连机制:自动重连和故障转移

2. 高级功能

  • 分布式锁:可重入锁、公平锁、读写锁、联锁、红锁
  • 分布式集合:Map、Set、List、Queue、Deque 等
  • 分布式对象:原子性 Long、BitSet、HyperLogLog 等
  • 分布式服务:远程服务、发布订阅、调度服务

Redisson 配置

Maven 依赖

<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.24.3</version> </dependency>

单机模式配置

Config config = new Config(); config.useSingleServer() .setAddress("redis://127.0.0.1:6379") .setPassword("yourpassword") .setDatabase(0) .setConnectionPoolSize(64) .setConnectionMinimumIdleSize(10); RedissonClient redisson = Redisson.create(config);

哨兵模式配置

Config config = new Config(); config.useSentinelServers() .addSentinelAddress("redis://sentinel1:26379", "redis://sentinel2:26379", "redis://sentinel3:26379") .setMasterName("mymaster") .setPassword("yourpassword"); RedissonClient redisson = Redisson.create(config);

集群模式配置

Config config = new Config(); config.useClusterServers() .addNodeAddress("redis://node1:6379", "redis://node2:6379", "redis://node3:6379") .setPassword("yourpassword") .setScanInterval(2000); RedissonClient redisson = Redisson.create(config);

Redisson 分布式锁详解

Redisson 实现了多种分布式锁,下面详细介绍每种锁的特性和使用方式。

1. 可重入锁(Reentrant Lock)

特性

  • 支持同一线程多次获取锁
  • 自动续期(看门狗机制)
  • 可设置锁超时时间
  • 阻塞式和非阻塞式获取

基本使用

// 获取锁对象 RLock lock = redisson.getLock("myLock"); // 阻塞式获取锁 lock.lock(); try { // 执行业务逻辑 System.out.println("执行业务代码"); } finally { // 释放锁 lock.unlock(); } // 尝试获取锁(非阻塞) if (lock.tryLock()) { try { // 执行业务逻辑 } finally { lock.unlock(); } } // 带超时的尝试获取 if (lock.tryLock(10, 30, TimeUnit.SECONDS)) { try { // 等待10秒获取锁,锁持有30秒 } finally { lock.unlock(); } }

看门狗机制

// 不指定超时时间,使用看门狗自动续期 lock.lock(); // 默认30秒自动续期 try { // 业务逻辑执行时间可以超过30秒 // 锁会自动续期,直到unlock() Thread.sleep(60000); } finally { lock.unlock(); }

自定义超时

// 指定超时时间,不使用看门狗 lock.lock(10, TimeUnit.SECONDS); try { // 10秒后锁自动释放,不会续期 } finally { lock.unlock(); }

2. 公平锁(Fair Lock)

特性

  • 按照请求顺序获取锁
  • 避免饥饿现象
  • 性能略低于可重入锁

使用方式

RLock fairLock = redisson.getFairLock("myFairLock"); // 阻塞式获取 fairLock.lock(); try { // 执行业务逻辑 } finally { fairLock.unlock(); } // 带超时的获取 if (fairLock.tryLock(10, 30, TimeUnit.SECONDS)) { try { // 执行业务逻辑 } finally { fairLock.unlock(); } }

3. 读写锁(ReadWrite Lock)

特性

  • 读锁(共享锁):多个线程可以同时持有
  • 写锁(排他锁):独占访问
  • 读读不互斥,读写互斥,写写互斥

使用方式

RReadWriteLock rwLock = redisson.getReadWriteLock("myRWLock"); // 读锁 RLock readLock = rwLock.readLock(); readLock.lock(); try { // 多个线程可以同时读取 String data = "读取数据"; System.out.println(data); } finally { readLock.unlock(); } // 写锁 RLock writeLock = rwLock.writeLock(); writeLock.lock(); try { // 独占写入 System.out.println("写入数据"); } finally { writeLock.unlock(); }

实际应用场景

// 缓存读写场景 public class CacheService { private RReadWriteLock rwLock; public CacheService(RedissonClient redisson) { this.rwLock = redisson.getReadWriteLock("cache:rwlock"); } public String getData(String key) { RLock readLock = rwLock.readLock(); readLock.lock(); try { // 读数据 return redisson.getBucket(key).get(); } finally { readLock.unlock(); } } public void setData(String key, String value) { RLock writeLock = rwLock.writeLock(); writeLock.lock(); try { // 写数据 redisson.getBucket(key).set(value); } finally { writeLock.unlock(); } } }

4. 联锁(MultiLock)

特性

  • 同时锁定多个对象
  • 所有锁都获取成功才算成功
  • 用于跨资源的一致性操作

使用方式

RLock lock1 = redisson1.getLock("lock1"); RLock lock2 = redisson2.getLock("lock2"); RLock lock3 = redisson3.getLock("lock3"); // 创建联锁 RLock multiLock = redisson.getMultiLock(lock1, lock2, lock3); try { // 同时获取多个锁 multiLock.lock(); // 执行跨资源的业务逻辑 } finally { multiLock.unlock(); }

5. 红锁(RedLock)

特性

  • 分布式高可用锁
  • 需要在多个 Redis 实例上加锁
  • 大多数节点成功才算成功
  • 防止单点故障

使用方式

// 配置多个Redis实例 Config config1 = new Config(); config1.useSingleServer().setAddress("redis://node1:6379"); RedissonClient redisson1 = Redisson.create(config1); Config config2 = new Config(); config2.useSingleServer().setAddress("redis://node2:6379"); RedissonClient redisson2 = Redisson.create(config2); Config config3 = new Config(); config3.useSingleServer().setAddress("redis://node3:6379"); RedissonClient redisson3 = Redisson.create(config3); // 获取红锁 RLock lock1 = redisson1.getLock("myRedLock"); RLock lock2 = redisson2.getLock("myRedLock"); RLock lock3 = redisson3.getLock("myRedLock"); RLock redLock = redisson1.getRedLock(lock1, lock2, lock3); try { // 大多数节点成功才获取锁 redLock.lock(); // 执行业务逻辑 } finally { redLock.unlock(); }

6. 信号量(Semaphore)

特性

  • 限制同时访问的线程数
  • 基于计数器实现
  • 支持公平和非公平模式

使用方式

RSemaphore semaphore = redisson.getSemaphore("mySemaphore"); // 设置许可数 semaphore.trySetPermits(3); try { // 获取许可 semaphore.acquire(); // 执行业务逻辑(最多3个线程同时执行) } finally { // 释放许可 semaphore.release(); } // 非阻塞获取 if (semaphore.tryAcquire()) { try { // 执行业务逻辑 } finally { semaphore.release(); } }

7. 闭锁(CountDownLatch)

特性

  • 等待多个线程完成
  • 基于计数器实现
  • 一次性使用

使用方式

RCountDownLatch latch = redisson.getCountDownLatch("myLatch"); // 设置等待数量 latch.trySetCount(5); // 等待线程 new Thread(() -> { try { latch.await(); System.out.println("所有线程执行完毕"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); // 工作线程 for (int i = 0; i < 5; i++) { new Thread(() -> { // 执行业务逻辑 System.out.println("工作线程执行"); // 计数减1 latch.countDown(); }).start(); }

Redisson 锁的最佳实践

1. 工具类封装

@Component public class DistributedLockUtil { @Autowired private RedissonClient redissonClient; /** * 执行带锁的业务逻辑 */ public <T> T executeWithLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit, Supplier<T> supplier) { RLock lock = redissonClient.getLock(lockKey); try { if (lock.tryLock(waitTime, leaseTime, unit)) { try { return supplier.get(); } finally { lock.unlock(); } } else { throw new RuntimeException("获取锁失败"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("锁等待被中断", e); } } /** * 无返回值的执行 */ public void executeWithLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit, Runnable runnable) { executeWithLock(lockKey, waitTime, leaseTime, unit, () -> { runnable.run(); return null; }); } }

2. 使用示例

@Service public class OrderService { @Autowired private DistributedLockUtil lockUtil; public void createOrder(String orderId) { lockUtil.executeWithLock( "order:lock:" + orderId, 10, // 等待10秒 30, // 锁持有30秒 TimeUnit.SECONDS, () -> { // 创建订单逻辑 System.out.println("创建订单: " + orderId); // 扣减库存 // 扣减余额 } ); } }

3. 注解方式实现

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface DistributedLock { String key(); long waitTime() default 10; long leaseTime() default 30; TimeUnit timeUnit() default TimeUnit.SECONDS; } @Aspect @Component public class DistributedLockAspect { @Autowired private RedissonClient redissonClient; @Around("@annotation(distributedLock)") public Object around(ProceedingJoinPoint point, DistributedLock distributedLock) throws Throwable { String lockKey = distributedLock.key(); RLock lock = redissonClient.getLock(lockKey); try { if (lock.tryLock(distributedLock.waitTime(), distributedLock.leaseTime(), distributedLock.timeUnit())) { try { return point.proceed(); } finally { lock.unlock(); } } else { throw new RuntimeException("获取锁失败"); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("锁等待被中断", e); } } } // 使用 @Service public class InventoryService { @DistributedLock(key = "inventory:lock:#{#productId}") public void deductInventory(String productId, int quantity) { // 扣减库存逻辑 } }

Redisson 锁的底层原理

1. 锁获取过程

1. 客户端发送 Lua 脚本到 Redis 2. Redis 原子执行:SET key value NX PX timeout 3. 如果成功,启动看门狗线程 4. 如果失败,返回获取失败

2. 看门狗续期机制

1. 默认续期时间:30秒 2. 续期线程:每 10 秒检查一次 3. 如果锁还持有,续期 30 秒 4. 直到调用 unlock() 停止续期

3. 锁释放过程

1. 客户端发送 Lua 脚本 2. 检查锁是否属于当前线程 3. 如果属于,删除 key 4. 如果不属于,返回释放失败

注意事项

  1. 锁名称设计:要保证唯一性和可读性
  2. 超时时间:根据业务执行时间合理设置
  3. 异常处理:确保锁能正确释放
  4. 避免死锁:设置合理的超时时间
  5. 性能考虑:锁粒度不宜过大
http://www.cnnetsun.cn/news/2090620.html

相关文章:

  • 算法训练营Day12| LeetCode 169. 多数元素
  • 2026年口碑优异的金相显微镜工厂盘点 有采购需求的建议收好
  • 宇宙学研究新突破:用 Blender 几何节点处理 CMB 数据,实现多项实用功能!
  • AI Agent在体育与娱乐领域的应用:数据分析与体验优化
  • HNU计算机系统期中题库详解(五)位运算与逻辑运算
  • 嵌入式团队紧急升级预警:VSCode 2026.1起废弃legacy GDB adapter——3类老旧JTAG探针将彻底失联?
  • KrkrzExtract终极指南:3步掌握krkrz引擎资源处理工具
  • 多线程下载引擎架构解析:AB Download Manager的技术实现路径
  • 如何快速掌握键盘控制鼠标:5个技巧让Windows操作更高效
  • 别再手动调色了!用JavaScript实现主题色自动生成9档深浅色(附完整代码)
  • TrollInstallerX:3分钟解锁iOS设备完整安装自由的专业指南
  • NVIDIA cuML FIL:GPU加速树模型推理性能优化指南
  • 告别Postman安装烦恼!Windows便携版终极解决方案完整指南
  • 别再傻傻分不清了!CAPL脚本里on signal、on envVar、on sysVar事件到底怎么用?
  • Android手机变身移动Linux服务器:Termux部署Ubuntu与SSH远程访问实战
  • 倾斜摄影OSGB数据处理避坑指南:从Smart3D导出到Cesium加载的完整链路解析
  • 为“干私活”删除公司AI训练数据,一程序员获刑五年十个月;百度反腐通报去年144名员工被查;GPT-5.5发布 | 极客头条
  • 【Python实战】从ValueError: negative dimensions出发,解析NumPy数组形状的动态计算与防御性编程
  • 【卷卷漫谈】你的opus4.6降智了吗?!Claude Code 质量翻车复盘
  • OBS多平台直播同步插件终极指南:一键实现5大平台同时推流
  • 实战指南:5个高效查询Materials Project API的核心技巧
  • 基于Ralphy框架构建本地化AI智能体:从原理到自动化工作流实践
  • 保姆级教程:用STM32CubeMX和HAL库搞定CAN总线与上位机通信(附完整源码)
  • Voxtral-4B-TTS-2603效果展示:德语科技新闻语音输出——辅音清晰度与长句断句实测
  • iperf3实战:从基础参数到高级场景的网络性能调优指南
  • 网络安全SRC漏洞挖掘学习路线 - (三):信息收集实战,找准SRC挖洞突破口
  • UEViewer深度解析:虚幻引擎资源逆向工程的架构设计与实现原理
  • 3分钟掌握MOOC课程离线下载:MoocDownloader终极指南
  • nnFormer实战:如何用Decathlon的BrainTumour数据集快速跑通3D医学分割?
  • STM32F4实战:手把手教你用FATFS和SDIO驱动外挂SD卡(附完整工程)