docs updated

pull/6258/head
Nikita Koksharov 3 months ago
parent 355b135627
commit 46868f2b4f

@ -1,4 +1,4 @@
# Redisson - Easy Redis Java client<br/>and Real-Time Data Platform
# Redisson - Valkey & Redis Java client<br/>Complete Real-Time Data Platform
High-performance async and lock-free Java client for Redis and Valkey based on [Netty](http://netty.io) framework.

@ -667,15 +667,32 @@ multimap.destroy();
_This feature is available only in [Redisson PRO](https://redisson.pro) edition._
Distributed Java implementation of Redis or Valkey based Key Value store for JSON objects. This object is thread-safe. Allows to store JSON value mapped by key. Operations can be executed per key or group of keys. Value is stored/retrieved using `JSON.*` commands. Both key and value are POJO objects.
[RJsonStore](https://www.javadoc.io/doc/org.redisson/redisson/latest/org/redisson/api/RJsonStore.html) is a distributed Key Value store for JSON objects. Compatible with Redis or Valkey. This object is thread-safe. Allows to store JSON value mapped by key. Operations can be executed per key or group of keys. Value is stored/retrieved using `JSON.*` commands. Both key and value are POJO objects.
Allows to define `time to live` parameter per entry. Doesn't use an entry eviction task, entries are cleaned on Redis or Valkey side.
Implements **Async**, **Reactive** and **RxJava3** interfaces.
Code example of **[Async](https://www.javadoc.io/doc/org.redisson/redisson/latest/org/redisson/api/RJsonStoreAsync.html) interface** usage:
```java
RJsonStoreAsync<String, MyObject> store = redisson.getJsonStore("test", new JacksonCodec(MyObject.class));
```
Code example of **[Reactive](https://static.javadoc.io/org.redisson/redisson/latest/org/redisson/api/RJsonStoreReactive.html) interface** usage:
```java
RedissonReactiveClient redisson = redissonClient.reactive();
RJsonStoreReactive<AnyObject> bucket = redisson.getJsonStore("anyObject", new JacksonCodec<>(AnyObject.class));
```
Code example of **[RxJava3](https://static.javadoc.io/org.redisson/redisson/latest/org/redisson/api/RJsonStoreRx.html) interface** usage:
```java
RedissonRxClient redisson = redissonClient.rxJava();
RJsonStoreRx<AnyObject> bucket = redisson.getJsonStore("anyObject", new JacksonCodec<>(AnyObject.class));
```
Data write code example:
```java
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", StringCodec.INSTANCE, new JacksonCodec(MyObject.class));
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", new JacksonCodec(MyObject.class));
MyObject t1 = new MyObject();
t1.setName("name1");
@ -705,7 +722,7 @@ store.setIfExists("1", t1);
Data read code example:
```java
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", StringCodec.INSTANCE, new JacksonCodec(MyObject.class));
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", new JacksonCodec(MyObject.class));
// multiple entries at once
Map<String, MyObject> entries = store.get(Set.of("1", "2"));
@ -717,7 +734,7 @@ MyObject value2 = store.get("2");
Data deletion code example:
```java
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", StringCodec.INSTANCE, new JacksonCodec(MyObject.class));
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", new JacksonCodec(MyObject.class));
// multiple entries at once
long deleted = store.delete(Set.of("1", "2"));
@ -727,7 +744,22 @@ boolean status = store.delete("1");
boolean status = store.delete("2");
```
For data searching index prefix should be defined in `<object_name>:` format. For example for object name "test" prefix is "test:".
Keys access code examples:
```java
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", new JacksonCodec(MyObject.class));
// iterate keys
Set<String> keys = store.keySet();
// read all keys at once
Set<String> keys = store.readAllKeySet();
```
### Search by Object properties
For data searching, index prefix should be defined in `<object_name>:` format. For example for object name "test" prefix is "test:".
`StringCodec` should be used as object codec to enable searching by field.
Data search code example:
```java
@ -758,17 +790,6 @@ AggregationResult ar = s.aggregate("idx", "*", AggregationOptions.defaults()
.withCursor().load("name"));
```
Keys access code examples:
```java
RJsonStore<String, MyObject> store = redisson.getJsonStore("test", StringCodec.INSTANCE, new JacksonCodec(MyObject.class));
// iterate keys
Set<String> keys = store.keySet();
// read all keys at once
Set<String> keys = store.readAllKeySet();
```
### Local Cache
Redisson provides [JSON Store](#json-store) implementation with local cache.
@ -912,54 +933,6 @@ boolean status = store.delete("1");
boolean status = store.delete("2");
```
For data searching index prefix should be defined in `<object_name>:` format. For example for object name "test" prefix is "test:".
Data search code example:
```java
RSearch s = redisson.getSearch();
s.createIndex("idx", IndexOptions.defaults()
.on(IndexType.JSON)
.prefix(Arrays.asList("test:")),
FieldIndex.text("name"));
LocalCachedJsonStoreOptions ops = LocalCachedJsonStoreOptions.name("test")
.keyCodec(StringCodec.INSTANCE)
.valueCodec(new JacksonCodec<>(MyObject.class));
RLocalCachedJsonStore<String, MyObject> store = redisson.getLocalCachedJsonStore(ops);
MyObject t1 = new MyObject();
t1.setName("name1");
MyObject t2 = new MyObject();
t2.setName("name2");
Map<String, MyObject> entries = new HashMap<>();
entries.put("1", t1);
entries.put("2", t2);
store.set(entries);
// search
SearchResult r = s.search("idx", "*", QueryOptions.defaults()
.returnAttributes(new ReturnAttribute("name")));
// aggregation
AggregationResult ar = s.aggregate("idx", "*", AggregationOptions.defaults()
.withCursor().load("name"));
```
Keys access code examples:
```java
LocalCachedJsonStoreOptions ops = LocalCachedJsonStoreOptions.name("test")
.keyCodec(StringCodec.INSTANCE)
.valueCodec(new JacksonCodec<>(MyObject.class));
RLocalCachedJsonStore<String, MyObject> store = redisson.getLocalCachedJsonStore(ops);
// iterate keys
Set<String> keys = store.keySet();
// read all keys at once
Set<String> keys = store.readAllKeySet();
```
## Set
Redis or Valkey based [Set](https://static.javadoc.io/org.redisson/redisson/latest/org/redisson/api/RSet.html) object for Java implements [Set](https://docs.oracle.com/javase/8/docs/api/java/util/Set.html) interface. This object is thread-safe. Keeps elements uniqueness via element state comparison. Set size limited to `4 294 967 295` elements. Redis or Valkey uses serialized state to check value uniqueness instead of value's `hashCode()`/`equals()` methods.

@ -290,26 +290,11 @@ set.removeListener(listenerId);
## JSON object holder
Java implementation of [RJsonBucket](https://static.javadoc.io/org.redisson/redisson/latest/org/redisson/api/RJsonBucket.html) object stores data in JSON format using `JSON.*` commands. JSON data encoding/decoding handled by `JsonCodec` which is a required parameter. Available implementation is `org.redisson.codec.JacksonCodec` which is thread-safe.
Use [JSON Store](collections.md/#json-store) for key-value implementation and local cache.
### Local cache
Redisson provides JSON object holder implementation with local cache.
**local cache** - so called near cache used to speed up read operations and avoid network roundtrips. It caches whole JSON object on Redisson side and executes read operations up to **45x faster** in comparison with common implementation. Local cache instances with the same name connected to the same pub/sub channel. This channel is used to exchange invalidate events between instances.
|RedissonClient<br/>method name | Local cache | Ultra-fast<br/>read/write |
| ------------- | :-----------: | :---------:|
|getJsonBucket()<br/><sub><i>open-source version</i></sub> | ❌ | ❌ |
|getJsonBucket()<br/><sub><i>[Redisson PRO](https://redisson.pro) version</i></sub> | ❌ | ✔️ |
|getLocalCachedJsonBucket()<br/><sub><i>[Redisson PRO](https://redisson.pro) version</i></sub> | ✔️ | ✔️ |
Use [JSON Store](collections.md/#json-store) for key-value implementation and local cache support.
Code example:
```java
RJsonBucket<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
// or local cached instance
RLocalCachedJsonBucket<AnyObject> bucket = redisson.getLocalCachedJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
bucket.set(new AnyObject(1));
AnyObject obj = bucket.get();
@ -325,8 +310,6 @@ long aa = bucket.arrayAppend("$.obj.values", "t3", "t4");
Code example of **[Async](https://static.javadoc.io/org.redisson/redisson/latest/org/redisson/api/RJsonBucketAsync.html) interface** usage:
```java
RJsonBucket<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
// or local cached instace
RLocalCachedJsonBucket<AnyObject> bucket = redisson.getLocalCachedJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
RFuture<Void> future = bucket.setAsync(new AnyObject(1));
RFuture<AnyObject> objfuture = bucket.getAsync();
@ -343,9 +326,6 @@ Code example of **[Reactive](https://static.javadoc.io/org.redisson/redisson/lat
```java
RedissonReactiveClient redisson = redissonClient.reactive();
RJsonBucketReactive<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
// or local cached instance
RLocalCachedJsonBucketReactive<AnyObject> bucket = redisson.getLocalCachedJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
Mono<Void> mono = bucket.set(new AnyObject(1));
Mono<AnyObject> objMono = bucket.get();
@ -362,8 +342,6 @@ Code example of **[RxJava3](https://static.javadoc.io/org.redisson/redisson/late
```java
RedissonRxClient redisson = redissonClient.rxJava();
RJsonBucketRx<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
// or local cached instance
RLocalCachedJsonBucketRx<AnyObject> bucket = redisson.getLocalCachedJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
Completable rx = bucket.set(new AnyObject(1));
Maybe<AnyObject> objRx = bucket.get();

@ -274,11 +274,11 @@ public class MyObject {
}
```
Please note: fields marked with `transient` keyword aren't stored in Redis.
Please note: fields marked with `transient` keyword aren't stored in Redis or Valkey.
To start use it you should use one of methods below:
`RLiveObjectService.attach()` - attaches object to Redis. Discard all the field values already in the detached instance
`RLiveObjectService.attach()` - attaches object to Redis or Valkey. Discard all the field values already in the detached instance
`RLiveObjectService.merge()` - overrides current object state in Redis or Valkey with the given object state
`RLiveObjectService.persist()` - stores only new object
@ -288,11 +288,11 @@ Code example:
RLiveObjectService service = redisson.getLiveObjectService();
MyLiveObject myObject = new MyLiveObject();
myObject1.setId("1");
// current state of myObject is now persisted and attached to Redis
// current state of myObject is now persisted and attached to Redis or Valkey
myObject = service.persist(myObject);
MyLiveObject myObject = new MyLiveObject("1");
// current state of myObject is now cleared and attached to Redis
// current state of myObject is now cleared and attached to Redis or Valkey
myObject = service.attach(myObject);
MyLiveObject myObject = new MyLiveObject();
@ -335,13 +335,13 @@ List.class | RedissonList.class
The conversion prefers the one nearer to the top of the table if a field type matches more than one entries. i.e. `LinkedList` implements `Deque`, `List`, `Queue`, it will be converted to a `RedissonDeque` because of this.
Instances of these Redisson classes retains their states/values/entries in Redis or Valkey too, changes to them are directly reflected into Redis or Valkey without keeping values in local VM.
Instances of these Redisson classes retains their states/values/entries in Redis or Valkey too, changes to them are directly reflected into database without keeping values in local VM.
### Search by Object properties
Redisson provides comprehensive search engine for Live Object. To make a property participate in search it should be annotated with `@RIndex` annotation.
Redisson provides comprehensive search engine for RLO objects. To make a property participate in search it should be annotated with `@RIndex` annotation.
!!! note "Open-source version of search engine is slow"
!!! note "The open-source version of the search engine is not optimized!"
Use [Redisson PRO](https://redisson.pro) for **ultra-fast search engine**, **low JVM memory consumption during search process** and **search index partitiong in cluster**.
Usage example:
@ -366,14 +366,14 @@ public class MyObject {
Different type of search conditions are available:
`Conditions.and` - **AND** condition for collection of nested conditions
`Conditions.eq` - **EQUALS** condition which restricts property to defined value
`Conditions.or` - **OR** condition for collection of nested conditions
`Conditions.in` - **IN** condition which restricts property to set of defined values
`Conditions.gt` - **GREATER THAN** condition which restricts property to defined value
`Conditions.ge` - **GREATER THAN ON EQUAL** condition which restricts property to defined value
`Conditions.lt` - **LESS THAN** condition which restricts property to defined value
`Conditions.le` - **LESS THAN ON EQUAL** condition which restricts property to defined value
`Conditions.and()` - **AND** condition for collection of nested conditions
`Conditions.eq()` - **EQUALS** condition which restricts property to defined value
`Conditions.or()` - **OR** condition for collection of nested conditions
`Conditions.in()` - **IN** condition which restricts property to set of defined values
`Conditions.gt()` - **GREATER THAN** condition which restricts property to defined value
`Conditions.ge()` - **GREATER THAN ON EQUAL** condition which restricts property to defined value
`Conditions.lt()` - **LESS THAN** condition which restricts property to defined value
`Conditions.le()` - **LESS THAN ON EQUAL** condition which restricts property to defined value
Once object stored in Redis or Valkey we can run search:
@ -392,6 +392,73 @@ Collection<MyObject> objects = liveObjectService.find(MyObject.class,
Search index expires after `expireXXX()` method call only if the Redis or Valkey `notify-keyspace-events` setting contains the letters `Kx`.
### Local Cache
_This feature is available only in [Redisson PRO](https://redisson.pro) edition._
RLO objects can be cached in local cache on the Redisson side.
**local cache** - so called near cache used to speed up read operations and avoid network roundtrips. It caches JSON Store entries on Redisson side and executes read operations up to **45x faster** in comparison with regular implementation. Local cached instances with the same name are connected to the same pub/sub channel. This channel is used for exchanging of update/invalidate events between all instances. Local cache store doesn't use `hashCode()`/`equals()` methods of key object, instead it uses hash of serialized state.
To make an RLO entity stored in local cache it should be annotated with `@RCache` annotation.
`@RCache` annotation settings:
* `storeCacheMiss` - defines whether to store a cache miss into the local cache. Default value is `false`.
* `storeMode` - defines store mode of cache data. Default value is `LOCALCACHE_REDIS`. Follow options are available:
* `LOCALCACHE` - store data in local cache only and use Redis or Valkey only for data update/invalidation.
* `LOCALCACHE_REDIS` - store data in both Redis or Valkey and local cache.
* `cacheProvider` - defines Cache provider used as local cache store. Default value is `REDISSON`. Follow options are available:
* `REDISSON` - uses Redisson own implementation
* `CAFFEINE` - uses Caffeine implementation
* `evictionPolicy` - defines local cache eviction policy. Default value is `NONE`. 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 soft references, entries are removed by GC
* `WEAK` - uses weak references, entries are removed by GC
* `NONE` - no eviction
* `cacheSize` - local cache size. If cache size is `0` then local cache is unbounded. If size is `-1` then local cache is always empty and doesn't store data. Default value is `0`.
* `reconnectionStrategy` - defines strategy for load missed local cache updates after connection failure. Default value is `NONE`. Follow options are available:
* `CLEAR` - clear local cache if map instance has been disconnected for a while.
* `NONE` - no reconnection handling
* `syncStrategy` - defines local cache synchronization strategy. Default value is `INVALIDATE`. Follow options are available:
* `INVALIDATE` - Default. Invalidate cache entry across all RLocalCachedJsonStore instances on map entry change
* `UPDATE` - Insert/update cache entry across all RLocalCachedJsonStore instances on map entry change
* `NONE` - No synchronizations on map changes
* `timeToLive` - defines time to live for each entry in local cache
* `maxIdle` - defines max idle time for each entry in local cache
* `useTopicPattern` - defines whether to use a global topic pattern listener that applies to all local cache instances belonging to the same Redisson instance. Default value is `true`.
Usage example:
```java
@REntity
@RCache(cacheSize = 10, evictionPolicy = EvictionPolicy.LRU)
public class MyObject {
@RId
private String id;
private String name;
private Integer counter;
}
RLiveObjectService service = redisson.getLiveObjectService();
MyObject obj = new MyObject();
obj.setId("1");
obj.setName("Simple name");
// current state of myObject is now persisted and attached to Redis or Valkey
myObject = service.persist(obj);
// loaded from local cache
String n = myObject.getName();
```
### Advanced Usage
As described before, RLO classes are proxy classes which can be fabricated when needed and then get cached in a `RedissonClient` instance against its original class. This process can be a bit slow and it is recommended to pre-register all the Redisson Live Object classes via `RedissonLiveObjectService` for any kind of delay-sensitive applications. The service can also be used to unregister a class if it is no longer needed. And of course it can be used to check if the class has already been registered.

Loading…
Cancel
Save