diff --git a/spring/redisson/redisson.md b/spring/redisson/redisson.md index 88518ae..3ee7e44 100644 --- a/spring/redisson/redisson.md +++ b/spring/redisson/redisson.md @@ -426,3 +426,154 @@ bucket.getAndSet(new AnyObject(6)); List values = bucket.get(new JacksonCodec<>(new TypeReference>() {}), "values"); long aa = bucket.arrayAppend("$.obj.values", "t3", "t4"); ``` +## 分布式集合 +### Map +基于Redis的分布式Map对象实现了ConcurrentMap接口。 +如果Map主要用于读取数据,或者像尽量避免网络请求,可以使用带有local cache的map,使用示例如下: +```java +RMap map = redisson.getMap("anyMap"); +SomeObject prevObject = map.put("123", new SomeObject()); +SomeObject currentObject = map.putIfAbsent("323", new SomeObject()); +SomeObject obj = map.remove("123"); + +// use fast* methods when previous value is not required +map.fastPut("a", new SomeObject()); +map.fastPutIfAbsent("d", new SomeObject()); +map.fastRemove("b"); + +RFuture putAsyncFuture = map.putAsync("321"); +RFuture fastPutAsyncFuture = map.fastPutAsync("321"); + +map.fastPutAsync("321", new SomeObject()); +map.fastRemoveAsync("321"); +``` +RMap支持为每个key绑定一个lock/readwritelock/semaphore/countdownlatch,使用如下: +```java +RMap map = redisson.getMap("anyMap"); +MyKey k = new MyKey(); +RLock keyLock = map.getLock(k); +keyLock.lock(); +try { + MyValue v = map.get(k); + // process value ... +} finally { + keyLock.unlock(); +} + +RReadWriteLock rwLock = map.getReadWriteLock(k); +rwLock.readLock().lock(); +try { + MyValue v = map.get(k); + // process value ... +} finally { + keyLock.readLock().unlock(); +} +``` +Redisson支持不同的Map结构实现,不同的实现主要包含如下三个特性: +- local cache: local cache通过将map entry缓存在redisson端来减少网络请求,从而提升读操作的性能。拥有相同name的local cache实例会连接到相同的发布/订阅channel,该channel用于在local cache实例之间交换更新/失效的事件。 +- eviction:支持对每个map entry指定ttl和max idle time + +如下是所有的RMap可用实现: +| RedissonClient method | local cache | eviction | +| :-: | :-: | :-: | +| getMap() | false | false | +| getMapCache() | false | true | +| getLocalCachedMap() | true | false | + +#### eviction +带有eviction功能的map实现了RMapCache接口,并且实现了ConcurrentMap接口。 +当前redis并不支持淘汰map entry的功能,故而超时的map entry是通过EvictionScheduler来时不时进行清理的。其会一次性移除100条超时的entry。任务启动的时间会自动调整,根据上次任务删除过期entry的数量,时间会在5s到半小时之间变化。 +建议在每个redisson实例中都使用具有相同名称的MapCache对象: +```java +RMapCache map = redisson.getMapCache("anyMap"); +// or +RMapCache map = redisson.getLocalCachedMapCache("anyMap", LocalCachedMapOptions.defaults()); +// or +RMapCache map = redisson.getClusteredLocalCachedMapCache("anyMap", LocalCachedMapOptions.defaults()); +// or +RMapCache map = redisson.getClusteredMapCache("anyMap"); + + +// ttl = 10 minutes, +map.put("key1", new SomeObject(), 10, TimeUnit.MINUTES); +// ttl = 10 minutes, maxIdleTime = 10 seconds +map.put("key1", new SomeObject(), 10, TimeUnit.MINUTES, 10, TimeUnit.SECONDS); + +// ttl = 3 seconds +map.putIfAbsent("key2", new SomeObject(), 3, TimeUnit.SECONDS); +// ttl = 40 seconds, maxIdleTime = 10 seconds +map.putIfAbsent("key2", new SomeObject(), 40, TimeUnit.SECONDS, 10, TimeUnit.SECONDS); + +// if object is not used anymore +map.destroy(); +``` +#### local cache +带有local cache功能的map实现实现了RLocalCachedMap接口,同时也实现了ConcurrentMap接口。 +推荐在所有的redisson client中使用具有相同name的LocalCachedMap,并且为所有具有相同名称的LocalCachedMap指定相同的LocalCachedMapOptions。 +如下是在创建localcachedmap时可以指定的options: +```java +LocalCachedMapOptions options = LocalCachedMapOptions.defaults() + + // Defines whether to store a cache miss into the local cache. + // Default value is false. + .storeCacheMiss(false); + + // Defines store mode of cache data. + // Follow options are available: + // LOCALCACHE - store data in local cache only and use Redis only for data update/invalidation. + // LOCALCACHE_REDIS - store data in both Redis and local cache. + .storeMode(StoreMode.LOCALCACHE_REDIS) + + // Defines Cache provider used as local cache store. + // Follow options are available: + // REDISSON - uses Redisson own implementation + // CAFFEINE - uses Caffeine implementation + .cacheProvider(CacheProvider.REDISSON) + + // Defines local cache eviction policy. + // Follow options are available: + // LFU - Counts how often an item was requested. Those that are used least often are discarded first. + // LRU - Discards the least recently used items first + // SOFT - Uses weak references, entries are removed by GC + // WEAK - Uses soft references, entries are removed by GC + // NONE - No eviction + .evictionPolicy(EvictionPolicy.NONE) + + // If cache size is 0 then local cache is unbounded. + .cacheSize(1000) + + // Defines strategy for load missed local cache updates after Redis connection failure. + // + // Follow reconnection strategies are available: + // CLEAR - Clear local cache if map instance has been disconnected for a while. + // LOAD - Store invalidated entry hash in invalidation log for 10 minutes + // Cache keys for stored invalidated entry hashes will be removed + // if LocalCachedMap instance has been disconnected less than 10 minutes + // or whole cache will be cleaned otherwise. + // NONE - Default. No reconnection handling + .reconnectionStrategy(ReconnectionStrategy.NONE) + + // Defines local cache synchronization strategy. + // + // Follow sync strategies are available: + // INVALIDATE - Default. Invalidate cache entry across all LocalCachedMap instances on map entry change + // UPDATE - Insert/update cache entry across all LocalCachedMap instances on map entry change + // NONE - No synchronizations on map changes + .syncStrategy(SyncStrategy.INVALIDATE) + + // time to live for each map entry in local cache + .timeToLive(10000) + // or + .timeToLive(10, TimeUnit.SECONDS) + + // max idle time for each map entry in local cache + .maxIdle(10000) + // or + .maxIdle(10, TimeUnit.SECONDS); +``` +localcachedmap对象在不再使用之后应该调用destroy方法进行销毁: +```java +RLocalCachedMap map = ... +map.destroy(); +``` +#### Map Persistence