完成redisson分布式锁文档的阅读

This commit is contained in:
2023-02-08 12:35:36 +08:00
parent 40918e6277
commit 36a2550982

View File

@@ -1,3 +1,87 @@
- [Redisson](#redisson)
- [配置](#配置)
- [编程式配置](#编程式配置)
- [yml Configuration](#yml-configuration)
- [Common Settings](#common-settings)
- [codec](#codec)
- [connectionListener](#connectionlistener)
- [nettyThreads](#nettythreads)
- [transportMode](#transportmode)
- [threads](#threads)
- [lockWatchdogTimeout](#lockwatchdogtimeout)
- [Mode](#mode)
- [single instance mode](#single-instance-mode)
- [Operation Execution](#operation-execution)
- [Async方式](#async方式)
- [Redisson Object的公共操作](#redisson-object的公共操作)
- [分布式对象](#分布式对象)
- [object holder](#object-holder)
- [RBucket](#rbucket)
- [RBuckets](#rbuckets)
- [Binary Stream Holder](#binary-stream-holder)
- [BitSet](#bitset)
- [AtomicLong](#atomiclong)
- [AtomicDouble](#atomicdouble)
- [Topic](#topic)
- [Reliable Topic](#reliable-topic)
- [Topic Pattern](#topic-pattern)
- [Bloom Filter](#bloom-filter)
- [HyperLogLog](#hyperloglog)
- [LongAdder](#longadder)
- [DoubleAdder](#doubleadder)
- [id generator](#id-generator)
- [Json Object Holder](#json-object-holder)
- [local cache](#local-cache)
- [分布式集合](#分布式集合)
- [Map](#map)
- [eviction](#eviction)
- [local cache](#local-cache-1)
- [Map Persistence](#map-persistence)
- [read-through策略](#read-through策略)
- [write-through(sync)策略](#write-throughsync策略)
- [write-behind策略(async)](#write-behind策略async)
- [Map Listener](#map-listener)
- [LRU/LFU bounded Map](#lrulfu-bounded-map)
- [MultiMap](#multimap)
- [Set based MultiMap](#set-based-multimap)
- [List based MultiMap](#list-based-multimap)
- [MultiMap eviction](#multimap-eviction)
- [Set](#set)
- [eviction](#eviction-1)
- [SortedSet](#sortedset)
- [ScoredSortedSet](#scoredsortedset)
- [LexSortedSet](#lexsortedset)
- [List](#list)
- [Queue](#queue)
- [Deque](#deque)
- [Blocking Queue](#blocking-queue)
- [Bounded Blocking Queue](#bounded-blocking-queue)
- [Blocking Deque](#blocking-deque)
- [Blocking Fair Queue](#blocking-fair-queue)
- [Blocking Fair Deque](#blocking-fair-deque)
- [DelayedQueue](#delayedqueue)
- [PriorityQueue](#priorityqueue)
- [PriorityDeque](#prioritydeque)
- [PriorityBlockingQueue](#priorityblockingqueue)
- [PriorityBlockingDeque](#priorityblockingdeque)
- [Stream](#stream)
- [RingBuffer](#ringbuffer)
- [Transfer Queue](#transfer-queue)
- [Time Series](#time-series)
- [分布式锁和synchronizer](#分布式锁和synchronizer)
- [Lock](#lock)
- [Fair Lock](#fair-lock)
- [MultiLock](#multilock)
- [ReadWriteLock](#readwritelock)
- [Semaphore](#semaphore)
- [PermitExpirableSemaphore](#permitexpirablesemaphore)
- [CountDownLatch](#countdownlatch)
- [SpinLock](#spinlock)
- [FencedLock](#fencedlock)
- [Redisson整合Spring Cache](#redisson整合spring-cache)
- [spring cache yaml config](#spring-cache-yaml-config)
# Redisson # Redisson
## 配置 ## 配置
### 编程式配置 ### 编程式配置
@@ -1211,4 +1295,295 @@ ts.remove(201908110508);
Collection<String> values = ts.pollFirst(2); Collection<String> values = ts.pollFirst(2);
Collection<String> range = ts.range(201908110501, 201908110508); Collection<String> range = ts.range(201908110501, 201908110508);
``` ```
## 分布式锁和synchronizer
### Lock
基于Redis的分布式ReentrantLock对象实现了java中的Lock接口。
为了防止redisson再获取锁之后崩溃导致永远持有锁redisson维护了watchdog当持有锁的redisson实例处于活跃状态时其会延长锁的时间。默认情况下redisson的超时时间为30s。
在获取锁时可以指定leaseTime在经过指定时间后锁定的lock会自动被释放。
> RLock的行为符合java lock规范意味着只有锁的持有线程才能对锁进行解锁否则会抛出IllegalMonitorStateException异常。
> 如果想要多个线程对锁资源进行操作可以考虑使用RSemaphore
RLock的使用示例如下
```java
RLock lock = redisson.getLock("myLock");
// traditional lock method
lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}
```
### Fair Lock
fair lock会保证所有线程按请求锁的顺序获取锁所有等待的线程会被排队如果有线程died那么redisson会等5s来等待其返回。
fair lock使用如下所示
```java
RLock lock = redisson.getFairLock("myLock");
// traditional lock method
lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}
```
### MultiLock
MultiLock允许对多个锁资源同时执行操作将多个锁资源视作单个锁资源。
MultiLock使用示例如下所示
```java
RLock lock1 = redisson1.getLock("lock1");
RLock lock2 = redisson2.getLock("lock2");
RLock lock3 = redisson3.getLock("lock3");
RLock multiLock = anyRedisson.getMultiLock(lock1, lock2, lock3);
// traditional lock method
multiLock.lock();
// or acquire lock and automatically unlock it after 10 seconds
multiLock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = multiLock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
multiLock.unlock();
}
}
```
### ReadWriteLock
基于Redis的ReadWriteLock实现了java中的ReadWriteLock接口readlock允许有多个ownerwritelock只允许有一个owner。
ReadWriteLock的使用示例如下所示
```java
RReadWriteLock rwlock = redisson.getReadWriteLock("myLock");
RLock lock = rwlock.readLock();
// or
RLock lock = rwlock.writeLock();
// traditional lock method
lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}
```
### Semaphore
基于Redis的Semaphore和java中的Semaphore类似可以在使用之前进行初始化但是初始化不是必须的可以通过trySetPermits方法初始化permit的数量。
semaphore使用示例如下所示
```java
RSemaphore semaphore = redisson.getSemaphore("mySemaphore");
// acquire single permit
semaphore.acquire();
// or acquire 10 permits
semaphore.acquire(10);
// or try to acquire permit
boolean res = semaphore.tryAcquire();
// or try to acquire permit or wait up to 15 seconds
boolean res = semaphore.tryAcquire(15, TimeUnit.SECONDS);
// or try to acquire 10 permit
boolean res = semaphore.tryAcquire(10);
// or try to acquire 10 permits or wait up to 15 seconds
boolean res = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
semaphore.release();
}
}
```
### PermitExpirableSemaphore
基于redis的分布式Semaphore对象其支持在通过acquire获取信号量时添加lease time参数。
对于带lease time的permit每个permit都通过id标识并且释放操作也是通过id释放。
允许通过addPermits方法增加或减少permits数量。
```java
RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore");
semaphore.trySetPermits(23);
// acquire permit
String id = semaphore.acquire();
// or acquire permit with lease time in 10 seconds
String id = semaphore.acquire(10, TimeUnit.SECONDS);
// or try to acquire permit
String id = semaphore.tryAcquire();
// or try to acquire permit or wait up to 15 seconds
String id = semaphore.tryAcquire(15, TimeUnit.SECONDS);
// or try to acquire permit with least time 15 seconds or wait up to 10 seconds
String id = semaphore.tryAcquire(10, 15, TimeUnit.SECONDS);
if (id != null) {
try {
...
} finally {
semaphore.release(id);
}
}
```
### CountDownLatch
基于Redis的分布式CountDownLatch对象和java中的CountDownLatch对象类似在使用之前应该通过trySetCount来进行初始化。
CountDownLatch的使用示例如下所示
```java
RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
latch.trySetCount(1);
// await for count down
latch.await();
// in other thread or JVM
RCountDownLatch latch = redisson.getCountDownLatch("myCountDownLatch");
latch.countDown();
```
### SpinLock
由于分布式锁是采用的pub/sub机制故而当短时间内获取或释放大量的锁时消息会通过pub/sub channel发送到redis集群中所有的节点。
可以通过backoff策略来自旋尝试从而代替pub/sub channel发送时间这样可以降低redis集群的网络和cpu负载。
```java
RLock lock = redisson.getSpinLock("myLock");
// traditional lock method
lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}
```
### FencedLock
FencedLock使用如下所示
```java
RFencedLock lock = redisson.getFencedLock("myLock");
// traditional lock method
Long token = lock.lockAndGetToken();
// or acquire lock and automatically unlock it after 10 seconds
token = lock.lockAndGetToken(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds
// and automatically unlock it after 10 seconds
Long token = lock.tryLockAndGetToken(100, 10, TimeUnit.SECONDS);
if (token != null) {
try {
// check if token >= old token
...
} finally {
lock.unlock();
}
}
```
## Redisson整合Spring Cache
Redisson提供了基于redis的spring cache实现每个cache实例都有ttl和maxIdleTime两个参数配置如下所示
```java
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson() throws IOException {
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://127.0.0.1:7004", "redis://127.0.0.1:7001");
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
// create "testMap" cache with ttl = 24 minutes and maxIdleTime = 12 minutes
config.put("testMap", new CacheConfig(24*60*1000, 12*60*1000));
return new RedissonSpringCacheManager(redissonClient, config);
}
}
```
cache配置也能从yaml文件中进行读取示例如下
```java
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson(@Value("classpath:/redisson.yaml") Resource configFile) throws IOException {
Config config = Config.fromYAML(configFile.getInputStream());
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) throws IOException {
return new RedissonSpringCacheManager(redissonClient, "classpath:/cache-config.yaml");
}
}
```
### spring cache yaml config
如下是通过yaml的格式来配置spring cache
```java
testMap:
ttl: 1440000
maxIdleTime: 720000
localCacheOptions:
invalidationPolicy: "ON_CHANGE"
evictionPolicy: "NONE"
cacheSize: 0
timeToLiveInMillis: 0
maxIdleInMillis: 0
```