参考:https://www.baeldung.com/tag/redis/ ---
对比
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();
秒杀减库存实现
存在问题,仅支持一个客户端
读写锁:读锁,支持高并发的读取;同时写锁,可控制只有一个客户端修改