【Redis】Redisson & 分布式锁常见问题
参考:https://www.baeldung.com/tag/redis/ ---
https://z.itpub.net/article/detail/97DA31532EE6D125C682EB1BBCDF67C0
分布式锁常见问题:
对比
Jedis: 直连,多线程操作不安全。可使用 jedis pool连接池;
redisson:支持分布式锁自动续期(后台watchdog线程检查是否执行完),提供分布锁能力(可重入锁、读写锁)
Spring Data Redis: RestTemplate指定序列化器:keySerializer,HashKeySerializer,ValueSerializer、HashValueSerializer
二、使用
https://redisson.org/ 参考官网首页的 Use Cases 和 Features
不需提前学习掌握redis命令;
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.16.2</version> </dependency>
具体使用参考:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
- Overview
概述 - Configuration
配置方法 - Operations execution
程序接口调用方式 - Data serialization
数据序列化 - Data partitioning (sharding)
单个集合数据分片(Sharding) - Distributed objects
分布式对象 - Distributed collections
分布式集合 - Distributed locks and synchronizers
分布式锁和同步器 - Distributed services
分布式服务 - Additional features
额外功能 - Redis commands mapping
Redis命令和Redisson对象匹配列表 - Standalone node
独立节点模式 - Tools
工具 - Integration with frameworks
第三方框架整合 - Dependency list
项目依赖列表 - FAQ
Redisson的锁自动续期原理
自动生成后台线程检测当前线程是否执行完,如果没执行完,则默认增加10s
问题:主从部署下,当Master挂掉后,Slave可能没同步到主节点的锁信息,所以仅满足AP,不满足C一致性
三、Code
参考:https://www.baeldung.com/tag/redis/
1、基础使用
- useSingleServer – for single node instance. Get single node settings here
- useMasterSlaveServers – for master with slave nodes. Get master-slave node settings here
- useSentinelServers – for sentinel nodes. Get sentinel node settings here
- useClusterServers – for clustered nodes. Get clustered node settings here
- useReplicatedServers – for replicated nodes. Get replicated node settings here
Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
2、Locks and Synchronizers
实现1:
RLock lock = redisson.getLock("myLock"); RFuture<Boolean> lockFuture = lock.tryLockAsync(100, 5, TimeUnit.SECONDS); lockFuture.whenComplete((res, exception) -> { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Sleep 10s"); lock.unlockAsync(); });
实现2:
Lock lock = redisson.getLock("myLock"); lock.lock(); try { }finally { lock.unlock(); }
读写锁 (确保多客户端对缓存数据库操作顺序),支撑分布式高并发分布式锁(如多个节点发起的的库存扣减)
1 RReadWriteLock lock = redisson.getReadWriteLock("lockKey"); 2 RLock rLock = lock.readLock(); 3 RLock wLock = lock.writeLock();
另外Redisson还通过加锁的方法提供了leaseTime
的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
// 10秒钟以后自动解锁
// 无需调用unlock方法手动解锁
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// 或
rwlock.writeLock().lock(10, TimeUnit.SECONDS);
// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// 或
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();
秒杀减库存实现
存在问题,仅支持一个客户端
读写锁:读锁,支持高并发的读取;同时写锁,可控制只有一个客户端修改
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)