完成redisson分布式锁文档的阅读
This commit is contained in:
@@ -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
|
||||
## 配置
|
||||
### 编程式配置
|
||||
@@ -1211,4 +1295,295 @@ ts.remove(201908110508);
|
||||
|
||||
Collection<String> values = ts.pollFirst(2);
|
||||
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允许有多个owner,writelock只允许有一个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
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user