完成redisson文档阅读
This commit is contained in:
@@ -577,3 +577,309 @@ RLocalCachedMap<String, Integer> map = ...
|
||||
map.destroy();
|
||||
```
|
||||
#### Map Persistence
|
||||
redisson允许将map中的数据存储到除了redis以外的空间,其通常用于和应用和数据库之间的缓存,类似于spring cache。
|
||||
##### read-through策略
|
||||
当请求的条目在redisson map object中不存在时,其会使用MapLoader对象来进行加载,示例代码如下:
|
||||
```java
|
||||
MapLoader<String, String> mapLoader = new MapLoader<String, String>() {
|
||||
|
||||
@Override
|
||||
public Iterable<String> loadAllKeys() {
|
||||
List<String> list = new ArrayList<String>();
|
||||
Statement statement = conn.createStatement();
|
||||
try {
|
||||
ResultSet result = statement.executeQuery("SELECT id FROM student");
|
||||
while (result.next()) {
|
||||
list.add(result.getString(1));
|
||||
}
|
||||
} finally {
|
||||
statement.close();
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String load(String key) {
|
||||
PreparedStatement preparedStatement = conn.prepareStatement("SELECT name FROM student where id = ?");
|
||||
try {
|
||||
preparedStatement.setString(1, key);
|
||||
ResultSet result = preparedStatement.executeQuery();
|
||||
if (result.next()) {
|
||||
return result.getString(1);
|
||||
}
|
||||
return null;
|
||||
} finally {
|
||||
preparedStatement.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
配置map的示例如下:
|
||||
```java
|
||||
MapOptions<K, V> options = MapOptions.<K, V>defaults()
|
||||
.loader(mapLoader);
|
||||
|
||||
RMap<K, V> map = redisson.getMap("test", options);
|
||||
// or
|
||||
RMapCache<K, V> map = redisson.getMapCache("test", options);
|
||||
// or with boost up to 45x times
|
||||
RLocalCachedMap<K, V> map = redisson.getLocalCachedMap("test", options);
|
||||
// or with boost up to 45x times
|
||||
RLocalCachedMapCache<K, V> map = redisson.getLocalCachedMapCache("test", options);
|
||||
```
|
||||
##### write-through(sync)策略
|
||||
如果map entry被更新,那么更新方法不会返回,直到通过MapWriter对象将entry更新写入到外部存储中:
|
||||
```java
|
||||
MapWriter<String, String> mapWriter = new MapWriter<String, String>() {
|
||||
|
||||
@Override
|
||||
public void write(Map<String, String> map) {
|
||||
PreparedStatement preparedStatement = conn.prepareStatement("INSERT INTO student (id, name) values (?, ?)");
|
||||
try {
|
||||
for (Entry<String, String> entry : map.entrySet()) {
|
||||
preparedStatement.setString(1, entry.getKey());
|
||||
preparedStatement.setString(2, entry.getValue());
|
||||
preparedStatement.addBatch();
|
||||
}
|
||||
preparedStatement.executeBatch();
|
||||
} finally {
|
||||
preparedStatement.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Collection<String> keys) {
|
||||
PreparedStatement preparedStatement = conn.prepareStatement("DELETE FROM student where id = ?");
|
||||
try {
|
||||
for (String key : keys) {
|
||||
preparedStatement.setString(1, key);
|
||||
preparedStatement.addBatch();
|
||||
}
|
||||
preparedStatement.executeBatch();
|
||||
} finally {
|
||||
preparedStatement.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
write-through策略配置如下:
|
||||
```java
|
||||
MapOptions<K, V> options = MapOptions.<K, V>defaults()
|
||||
.writer(mapWriter)
|
||||
.writeMode(WriteMode.WRITE_BEHIND)
|
||||
.writeBehindDelay(5000)
|
||||
.writeBehindBatchSize(100);
|
||||
|
||||
RMap<K, V> map = redisson.getMap("test", options);
|
||||
// or
|
||||
RMapCache<K, V> map = redisson.getMapCache("test", options);
|
||||
// or with boost up to 45x times
|
||||
RLocalCachedMap<K, V> map = redisson.getLocalCachedMap("test", options);
|
||||
// or with boost up to 45x times
|
||||
RLocalCachedMapCache<K, V> map = redisson.getLocalCachedMapCache("test", options);
|
||||
```
|
||||
##### write-behind策略(async)
|
||||
在使用write-behind之后,对于map object的修改是批量累计的,并且按定义的延迟异步被MapWriter写入到外部存储中。
|
||||
writeBehindDelay是批量写入或删除的延迟,默认情况下值为1000ms。writeBehindBatchSize是batch的容量,每个batch都包含写入和删除的命令集合,默认情况下size是50 .
|
||||
配置代码如下所示:
|
||||
```java
|
||||
MapOptions<K, V> options = MapOptions.<K, V>defaults()
|
||||
.writer(mapWriter)
|
||||
.writeMode(WriteMode.WRITE_BEHIND)
|
||||
.writeBehindDelay(5000)
|
||||
.writeBehindBatchSize(100);
|
||||
|
||||
RMap<K, V> map = redisson.getMap("test", options);
|
||||
// or
|
||||
RMapCache<K, V> map = redisson.getMapCache("test", options);
|
||||
// or with boost up to 45x times
|
||||
RLocalCachedMap<K, V> map = redisson.getLocalCachedMap("test", options);
|
||||
// or with boost up to 45x times
|
||||
RLocalCachedMapCache<K, V> map = redisson.getLocalCachedMapCache("test", options);
|
||||
```
|
||||
#### Map Listener
|
||||
Redisson允许为实现RMapCache接口的Map对象绑定监听器,监听如下的map事件:
|
||||
- entry创建:org.redisson.api.map.event.EntryCreatedListener
|
||||
- entry过期:org.redisson.api.map.event.EntryExpiredListener
|
||||
- entry移除:org.redisson.api.map.event.EntryRemovedListener
|
||||
- entry更新:org.redisson.api.map.event.EntryUpdatedListener
|
||||
|
||||
使用实例如下所示:
|
||||
```java
|
||||
RMapCache<String, SomeObject> map = redisson.getMapCache("anyMap");
|
||||
// or
|
||||
RMapCache<String, SomeObject> map = redisson.getLocalCachedMapCache("anyMap", LocalCachedMapOptions.defaults());
|
||||
// or
|
||||
RMapCache<String, SomeObject> map = redisson.getClusteredLocalCachedMapCache("anyMap", LocalCachedMapOptions.defaults());
|
||||
// or
|
||||
RMapCache<String, SomeObject> map = redisson.getClusteredMapCache("anyMap");
|
||||
|
||||
|
||||
int updateListener = map.addListener(new EntryUpdatedListener<Integer, Integer>() {
|
||||
@Override
|
||||
public void onUpdated(EntryEvent<Integer, Integer> event) {
|
||||
event.getKey(); // key
|
||||
event.getValue() // new value
|
||||
event.getOldValue() // old value
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
int createListener = map.addListener(new EntryCreatedListener<Integer, Integer>() {
|
||||
@Override
|
||||
public void onCreated(EntryEvent<Integer, Integer> event) {
|
||||
event.getKey(); // key
|
||||
event.getValue() // value
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
int expireListener = map.addListener(new EntryExpiredListener<Integer, Integer>() {
|
||||
@Override
|
||||
public void onExpired(EntryEvent<Integer, Integer> event) {
|
||||
event.getKey(); // key
|
||||
event.getValue() // value
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
int removeListener = map.addListener(new EntryRemovedListener<Integer, Integer>() {
|
||||
@Override
|
||||
public void onRemoved(EntryEvent<Integer, Integer> event) {
|
||||
event.getKey(); // key
|
||||
event.getValue() // value
|
||||
// ...
|
||||
}
|
||||
});
|
||||
|
||||
map.removeListener(updateListener);
|
||||
map.removeListener(createListener);
|
||||
map.removeListener(expireListener);
|
||||
map.removeListener(removeListener);
|
||||
```
|
||||
#### LRU/LFU bounded Map
|
||||
实现了RMapCache接口的Map对象支持按LRU或LFU顺序进行绑定。绑定了LRU或LFU的Map可以存储固定数量的entry,并且按照LRU或LFU的顺序淘汰entry。
|
||||
```java
|
||||
RMapCache<String, SomeObject> map = redisson.getMapCache("anyMap");
|
||||
// or
|
||||
RMapCache<String, SomeObject> map = redisson.getLocalCachedMapCache("anyMap", LocalCachedMapOptions.defaults());
|
||||
// or
|
||||
RMapCache<String, SomeObject> map = redisson.getClusteredLocalCachedMapCache("anyMap", LocalCachedMapOptions.defaults());
|
||||
// or
|
||||
RMapCache<String, SomeObject> map = redisson.getClusteredMapCache("anyMap");
|
||||
|
||||
|
||||
// tries to set limit map to 10 entries using LRU eviction algorithm
|
||||
map.trySetMaxSize(10);
|
||||
// ... using LFU eviction algorithm
|
||||
map.trySetMaxSize(10, EvictionMode.LFU);
|
||||
|
||||
// set or change limit map to 10 entries using LRU eviction algorithm
|
||||
map.setMaxSize(10);
|
||||
// ... using LFU eviction algorithm
|
||||
map.setMaxSize(10, EvictionMode.LFU);
|
||||
|
||||
map.put("1", "2");
|
||||
map.put("3", "3", 1, TimeUnit.SECONDS);
|
||||
```
|
||||
### MultiMap
|
||||
基于Redis的MultiMap支持为一个key绑定多个value
|
||||
#### Set based MultiMap
|
||||
基于set的multimap实现对于相同的key不允许出现重复的value:
|
||||
```java
|
||||
RSetMultimap<SimpleKey, SimpleValue> map = redisson.getSetMultimap("myMultimap");
|
||||
map.put(new SimpleKey("0"), new SimpleValue("1"));
|
||||
map.put(new SimpleKey("0"), new SimpleValue("2"));
|
||||
map.put(new SimpleKey("3"), new SimpleValue("4"));
|
||||
|
||||
Set<SimpleValue> allValues = map.get(new SimpleKey("0"));
|
||||
|
||||
List<SimpleValue> newValues = Arrays.asList(new SimpleValue("7"), new SimpleValue("6"), new SimpleValue("5"));
|
||||
Set<SimpleValue> oldValues = map.replaceValues(new SimpleKey("0"), newValues);
|
||||
|
||||
Set<SimpleValue> removedValues = map.removeAll(new SimpleKey("0"));
|
||||
```
|
||||
#### List based MultiMap
|
||||
基于List的MultiMap允许对相同的key存在多个相同value,并且对同一个key其value按插入顺序存储:
|
||||
```java
|
||||
RListMultimap<SimpleKey, SimpleValue> map = redisson.getListMultimap("test1");
|
||||
map.put(new SimpleKey("0"), new SimpleValue("1"));
|
||||
map.put(new SimpleKey("0"), new SimpleValue("2"));
|
||||
map.put(new SimpleKey("0"), new SimpleValue("1"));
|
||||
map.put(new SimpleKey("3"), new SimpleValue("4"));
|
||||
|
||||
List<SimpleValue> allValues = map.get(new SimpleKey("0"));
|
||||
|
||||
Collection<SimpleValue> newValues = Arrays.asList(new SimpleValue("7"), new SimpleValue("6"), new SimpleValue("5"));
|
||||
List<SimpleValue> oldValues = map.replaceValues(new SimpleKey("0"), newValues);
|
||||
|
||||
List<SimpleValue> removedValues = map.removeAll(new SimpleKey("0"));
|
||||
```
|
||||
#### MultiMap eviction
|
||||
对于实现了MultimapCache接口的map对象,分别支持基于list和基于set的evicition。
|
||||
过期的entry清除由EvictionScheduler执行,其一次性会移除100条过期的entry。Task启动时间会根据上次任务删除的条目数目自动进行调整,时间间隔在1s和2h之间进行调整。
|
||||
MultiMap eviction使用示例如下所示:
|
||||
```java
|
||||
RSetMultimapCache<String, String> multimap = redisson.getSetMultimapCache("myMultimap");
|
||||
multimap.put("1", "a");
|
||||
multimap.put("1", "b");
|
||||
multimap.put("1", "c");
|
||||
|
||||
multimap.put("2", "e");
|
||||
multimap.put("2", "f");
|
||||
|
||||
multimap.expireKey("2", 10, TimeUnit.MINUTES);
|
||||
```
|
||||
### Set
|
||||
基于redis的set object实现了java.util.set接口。
|
||||
redis set的使用如下所示:
|
||||
```java
|
||||
RSet<SomeObject> set = redisson.getSet("anySet");
|
||||
set.add(new SomeObject());
|
||||
set.remove(new SomeObject());
|
||||
```
|
||||
根据是否支持数据淘汰,可以分为如下方法:
|
||||
| Redisson Client method | Eviction Support |
|
||||
| :-: | :-: |
|
||||
| getSet() | false |
|
||||
|getSetCache() | true |
|
||||
#### eviction
|
||||
支持淘汰功能的Set对象实现了RSetCache接口,当前redis尚不支持淘汰set中的值,故而淘汰是由EvictionScheduler实现的,其一次性移除300条entry,根据上次task淘汰的key数量,下次执行task的间隔在1s到1h之间调整。
|
||||
```java
|
||||
RSetCache<SomeObject> set = redisson.getSetCache("mySet");
|
||||
// or
|
||||
RMapCache<SomeObject> set = redisson.getClusteredSetCache("mySet");
|
||||
|
||||
// ttl = 10 minutes,
|
||||
set.add(new SomeObject(), 10, TimeUnit.MINUTES);
|
||||
|
||||
// if object is not used anymore
|
||||
set.destroy();
|
||||
```
|
||||
#### SortedSet
|
||||
基于Redis的SortedSet实现了java.util.SortedSet接口,其通过比较元素来确保元素的在set中的唯一性。对于String数据类型,更推荐使用LexSortedSet,其性能表现更好。
|
||||
RSortedSet的使用示例如下所示:
|
||||
```java
|
||||
RSortedSet<Integer> set = redisson.getSortedSet("anySet");
|
||||
set.trySetComparator(new MyComparator()); // set object comparator
|
||||
set.add(3);
|
||||
set.add(1);
|
||||
set.add(2);
|
||||
|
||||
set.removeAsync(0);
|
||||
set.addAsync(5);
|
||||
```
|
||||
#### ScoredSortedSet
|
||||
基于redis的分布式ScoredSortedSet根据插入元素时的score来对元素进行排序。使用示例如下所示:
|
||||
```java
|
||||
set.add(0.13, new SomeObject(a, b));
|
||||
set.addAsync(0.251, new SomeObject(c, d));
|
||||
set.add(0.302, new SomeObject(g, d));
|
||||
|
||||
set.pollFirst();
|
||||
set.pollLast();
|
||||
|
||||
int index = set.rank(new SomeObject(g, d)); // get element index
|
||||
Double score = set.getScore(new SomeObject(g, d)); // get element score
|
||||
```
|
||||
Reference in New Issue
Block a user