Use cases of redis redisson collection of RList Rset RMap
- 2021-10-16 01:44:14
- OfStack
redis redisson Set Operation
Related classes and interfaces
Rlist: Linked list
public interface RList<V> extends List<V>, RExpirable, RListAsync<V>, RSortable<List<V>>, RandomAccess {
List<V> get(int... var1); // Gets the specified node value
int addAfter(V var1, V var2); // In var1 Add before var2
int addBefore(V var1, V var2); // In var1 Add after var2
void fastSet(int var1, V var2); // Modify var1 Only for var2
List<V> readAll(); // Get all the values of the linked list
RList<V> subList(int var1, int var2); // Get var1 To var2 Sublinked list of
List<V> range(int var1); // Return var1 Back linked list
List<V> range(int var1, int var2); // Return var1 To var2 Linked list of
void trim(int var1, int var2); // Reservation var1 To var2 The linked list at, and the rest is deleted
void fastRemove(int var1); // Delete var1 Value at
boolean remove(Object var1, int var2); // Determine whether the element is deleted
<KOut, VOut> RCollectionMapReduce<V, KOut, VOut> mapReduce(); //mapreduce Operation
}
RSet: Unordered Set
public interface RSet<V> extends Set<V>, RExpirable, RSetAsync<V>, RSortable<Set<V>> {
V removeRandom();
Set<V> removeRandom(int var1); // Delete an object
V random();
Set<V> random(int var1); // Random return object
boolean move(String var1, V var2); // Judgment set var1 Does it exist in var2 , similar contains() Method
Set<V> readAll(); // Get all objects
int union(String... var1); // Number of set union objects
Set<V> readUnion(String... var1); // Set union
int diff(String... var1); // Number of set difference set objects
Set<V> readDiff(String... var1); // Set difference set
int intersection(String... var1); // Number of objects intersected by sets
Set<V> readIntersection(String... var1); // Set intersection
Iterator<V> iterator(int var1);
Iterator<V> iterator(String var1, int var2);
Iterator<V> iterator(String var1); // Traversing the set
<KOut, VOut> RCollectionMapReduce<V, KOut, VOut> mapReduce();
RSemaphore getSemaphore(V var1);
RCountDownLatch getCountDownLatch(V var1);
RPermitExpirableSemaphore getPermitExpirableSemaphore(V var1); // Semaphore
RLock getLock(V var1);
RLock getFairLock(V var1);
RReadWriteLock getReadWriteLock(V var1); // Lock operation
Stream<V> stream(int var1);
Stream<V> stream(String var1, int var2);
Stream<V> stream(String var1); // Flow operation
}
RMap: Key-value pairs
public interface RMap<K, V> extends ConcurrentMap<K, V>, RExpirable, RMapAsync<K, V> {
void loadAll(boolean var1, int var2);
void loadAll(Set<? extends K> var1, boolean var2, int var3);
V get(Object var1); // Get var1 Value of
V put(K var1, V var2); // Add Object
V putIfAbsent(K var1, V var2); // Object does not exist
V replace(K var1, V var2); // Replace object
boolean replace(K var1, V var2, V var3); // Replace object
V remove(Object var1); // Remove Object
boolean remove(Object var1, Object var2); // Remove Object
void putAll(Map<? extends K, ? extends V> var1);
void putAll(Map<? extends K, ? extends V> var1, int var2); // Add Object
Map<K, V> getAll(Set<K> var1); // Get key In the collection var1 Key-value pairs in
int valueSize(K var1); //key For var1 Adj. value Size
V addAndGet(K var1, Number var2); //key For var1 Adj. value Plus var2
long fastRemove(K... var1); // Remove Object
boolean fastPut(K var1, V var2); // Add Object
boolean fastReplace(K var1, V var2); // Replace key For var1 The value of is var2
boolean fastPutIfAbsent(K var1, V var2); // If it does not exist, set
Set<K> readAllKeySet(); // Get all key , to set Formal return
Collection<V> readAllValues(); // Get all value , to collection Return
Set<Entry<K, V>> readAllEntrySet(); // Traversing key-value pairs
Map<K, V> readAllMap(); // Collection form is converted to map Type
Set<K> keySet();
Set<K> keySet(int var1);
Set<K> keySet(String var1, int var2);
Set<K> keySet(String var1); // Get key Set
Collection<V> values();
Collection<V> values(String var1);
Collection<V> values(String var1, int var2);
Collection<V> values(int var1); // Get all value
Set<Entry<K, V>> entrySet();
Set<Entry<K, V>> entrySet(String var1);
Set<Entry<K, V>> entrySet(String var1, int var2);
Set<Entry<K, V>> entrySet(int var1); // Traversing key-value pairs
<KOut, VOut> RMapReduce<K, V, KOut, VOut> mapReduce();
RSemaphore getSemaphore(K var1);
RCountDownLatch getCountDownLatch(K var1);
RPermitExpirableSemaphore getPermitExpirableSemaphore(K var1); // Semaphore operation
RLock getLock(K var1);
RLock getFairLock(K var1);
RReadWriteLock getReadWriteLock(K var1); // Lock operation
}
Use sample
public class MyTest {
public static void main(String[] args){
Config config=new Config();
config.useSingleServer().setAddress("redis://******:6379").setPassword("123456");
RedissonClient client= Redisson.create(config);
RList<String> list=client.getList("list");
for (int i=0;i<10;i++){
list.add(" Gua Tian Li Xia "+i);
}
list.readAll().forEach(System.out::println);
System.out.println("list The number of is: "+list.size()+"\n");
RSet<String> set=client.getSet("set");
for (int i=0;i<10;i++){
set.add(" Gua Tian Li Xia "+i);
}
for (String s : set) {
System.out.println(s);
}
System.out.println("set Is the size of: "+set.size()+"\n");
RMap<Integer,String> map=client.getMap("map");
for (int i=0;i<10;i++){
map.put(i," Gua Tian Li Xia "+i);
}
for (Map.Entry<Integer,String> entry:map.entrySet()){
System.out.println(entry.getKey()+" ==> "+entry.getValue());
}
System.out.println("map Is the size of: "+map.size());
}
}
Console output
Gua Tian Li Xia 0
Gua Tian Li Xia 1
Gua Tian Li Xia 2
Gua Tian Li Xia 3
Gua Tian Li Xia 4
Gua Tian Li Xia 5
Gua Tian Li Xia 6
Gua Tian Li Xia 7
Gua Tian Li Xia 8
Gua Tian Li Xia 9
The number of list is: 10
Gua Tian Li Xia 0
Gua Tian Li Xia 1
Gua Tian Li Xia 7
Gua Tian Li Xia 3
Gua Tian Li Xia 5
Gua Tian Li Xia 4
Gua Tian Li Xia 9
Gua Tian Li Xia 8
Gua Tian Li Xia 6
Gua Tian Li Xia 2
Size of set: 10
0 == > Gua Tian Li Xia 0
1 == > Gua Tian Li Xia 1
2 == > Gua Tian Li Xia 2
3 == > Gua Tian Li Xia 3
4 == > Gua Tian Li Xia 4
5 == > Gua Tian Li Xia 5
6 == > Gua Tian Li Xia 6
7 == > Gua Tian Li Xia 7
8 == > Gua Tian Li Xia 8
9 == > Gua Tian Li Xia 9
The size of map is: 10
Matters needing attention in using Redisson
Redisson is an Java in-memory data grid implemented on the basis of Redis. Compared with Jedis, which exposes the underlying operations, Redisson provides a series of distributed Java common objects and many distributed services.
Characteristic & Functions:
Support Redis Single Node (single) Mode, Sentinel (sentinel) Mode, Master-Slave (Master/Slave) Mode, and Cluster (Redis Cluster) Mode The program interface is called by asynchronous execution and asynchronous flow execution Data serialization, Redisson object coding class is used to serialize and deserialize the object, in order to achieve the object in Redis read and store Single collection data fragmentation. In cluster mode, Redisson provides automatic fragmentation for a single Redis collection type Provides a variety of distributed objects, such as: Object Bucket, Bitset, AtomicLong, Bloom Filter, HyperLogLog, and so on Provide rich distributed collections, such as Map, Multimap, Set, SortedSet, List, Deque, Queue, etc. Realization of distributed lock and synchronizer, reentrant lock (Reentrant Lock), fair lock (Fair Lock), interlock (MultiLock), red lock (Red Lock), semaphore (Semaphonre), expired signal lock (PermitExpirableSemaphore), etc Provides advanced distributed services such as distributed remote services (Remote Service), distributed real-time object (Live Object) services, distributed execution services (Executor Service), distributed scheduling task services (Schedule Service), and distributed mapping induction services (MapReduce) For more features and functions, please pay attention to official website: http://redisson.orgImplementation principle
redis itself does not support the above-mentioned distributed objects and collections. Redisson realizes advanced data structures and characteristics on the client side by using the characteristics of redis, such as the realization of priority queue, which is sorted by the client side and then stored in redis.
Client implementation means that when no client is online, all these data structures and features will not be preserved or automatically effective, such as the triggering of expired events or the addition of elements to the original priority queue.
Matters needing attention
Real-timeRMap has a function that can set the expiration time of key-value pairs and register event listeners for key-value pairs
Element elimination function (Eviction) The distributed RMapCache Java object of Redisson implements the elimination mechanism for a single element based on RMap. While still preserving the insertion order of elements. Because RMapCache is implemented based on RMap, it inherits both java. util. concurrent. ConcurrentMap and java. util. Map interfaces. Spring Cache integration provided by Redisson and JCache are based on this function. The current Redis itself does not support element elimination in hashing (Hash), so all expired elements are regularly cleaned through org. redisson. EvictionScheduler instances. In order to ensure the effective use of resources, each run cleans up to 300 expired elements. The start time of the task will be automatically adjusted according to the actual number of cleanups last time, and the interval will be between 1 second and 1 hour. For example, if 300 elements are deleted during this cleanup, the next cleanup will be performed after 1 second (minimum interval). 1 Once the cleaning quantity is less than the last cleaning quantity, the time interval will increase by 1.5 times.As stated in the official wiki, this function is cleaned regularly by background threads, so this is non-real-time (issue-1234: on expired event is not executed in real-time.), and the delay is between 5 seconds and 2 hours, so scenes with high real-time requirements have to be measured by themselves.
Due to the non-real-time nature of the expiration time, the occurrence of the expiration event is also non-real-time, and the corresponding listener may be delayed for a while before receiving the notification. In my test, the error of setting ttl at the second level is relatively large, while the minute level ttl is not bad (setting value on the left side, actual time consumption on the right side):
Serialization1s _ 5s
3s _ 5s
4s _ 5s
5s _ 9s
6s _ 10s
10s _ 15s
1m _ 1m11s
The default encoder by Redisson is JsonJacksonCodec, and JsonJackson has an infinite loop exception when serializing objects with bidirectional references. fastjson will automatically replace it with the reference $ref after checking out the bidirectional reference, ending the loop.
In my case, I serialized an service, which was hosted by spring and injected with another service. With fastjson, it can be serialized to redis normally, while JsonJackson throws an infinite loop exception.
In order to make the serialized content visible, the encoder is realized by itself without other binary encoders provided by redission:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import org.redisson.client.codec.BaseCodec;
import org.redisson.client.protocol.Decoder;
import org.redisson.client.protocol.Encoder;
import java.io.IOException;
public class FastjsonCodec extends BaseCodec {
private final Encoder encoder = in -> {
ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
try {
ByteBufOutputStream os = new ByteBufOutputStream(out);
JSON.writeJSONString(os, in,SerializerFeature.WriteClassName);
return os.buffer();
} catch (IOException e) {
out.release();
throw e;
} catch (Exception e) {
out.release();
throw new IOException(e);
}
};
private final Decoder<Object> decoder = (buf, state) ->
JSON.parseObject(new ByteBufInputStream(buf), Object.class);
@Override
public Decoder<Object> getValueDecoder() {
return decoder;
}
@Override
public Encoder getValueEncoder() {
return encoder;
}
}
Subscribe to Publication
The encapsulation of Redisson for subscribed publications is RTopic, which is also the implementation principle of many event listening in Redisson (for example, event listening for key-value pairs).
When you use unit tests, you find that after an event is published, subscribers need to delay 1 time before receiving the event. Specific reasons to be investigated