|
| 1 | +[[redis:reactive]] |
| 2 | += Reactive Redis support |
| 3 | +:referenceDir: . |
| 4 | + |
| 5 | +This section covers reactive Redis support and how to get started. You will find certain overlaps with the <<redis,imperative Redis support>>. |
| 6 | + |
| 7 | +[[redis:reactive:requirements]] |
| 8 | +== Redis Requirements |
| 9 | + |
| 10 | +Spring Redis requires Redis 2.6 or above and Java SE 8.0 or above. In terms of language bindings (or connectors), Spring Data Redis integrates with http://github.com/lettuce-io/lettuce-core[Lettuce] as the only reactive Java connector. Spring Data Redis uses https://projectreactor.io/[Project Reactor] as reactive composition library. |
| 11 | + |
| 12 | +[[redis:reactive:connectors]] |
| 13 | +== Connecting to Redis using a reactive driver |
| 14 | + |
| 15 | +One of the first tasks when using Redis and Spring is to connect to the store through the IoC container. To do that, a Java connector (or binding) is required. No matter the library one chooses, there is only one set of Spring Data Redis API that one needs to use that behaves consistently across all connectors, namely the `org.springframework.data.redis.connection` package and its `ReactiveRedisConnection` and `ReactiveRedisConnectionFactory` interfaces for working with and retrieving active `connections` to Redis. |
| 16 | + |
| 17 | +[[redis:reactive:connectors:operation-modes]] |
| 18 | +=== Redis Operation Modes |
| 19 | + |
| 20 | +Redis can be run as Standalone server, with <<redis:sentinel,Redis Sentinel>> or in <<cluster,Redis Cluster>> mode. |
| 21 | +http://github.com/lettuce-io/lettuce-core[Lettuce] supports all above mentioned connection types. |
| 22 | + |
| 23 | +[[redis:reactive:connectors:connection]] |
| 24 | +=== ReactiveRedisConnection and ReactiveRedisConnectionFactory |
| 25 | + |
| 26 | +`ReactiveRedisConnection` provides the building block for Redis communication as it handles the communication with the Redis back-end. It also automatically translates the underlying connecting library exceptions to Spring's consistent DAO exception http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/data-access.html#dao-exceptions[hierarchy] so one can switch the connectors without any code changes as the operation semantics remain the same. |
| 27 | + |
| 28 | +Active ``ReactiveRedisConnection``s are created through `ReactiveRedisConnectionFactory`. In addition, the factories act as ``PersistenceExceptionTranslator``s, meaning once declared, they allow one to do transparent exception translation. For example, exception translation through the use of the `@Repository` annotation and AOP. For more information see the dedicated http://docs.spring.io/spring/docs/{springVersion}/spring-framework-reference/data-access.html#orm-exception-translation[section] in Spring Framework documentation. |
| 29 | + |
| 30 | +NOTE: Depending on the underlying configuration, the factory can return a new connection or an existing connection (in case a pool or shared native connection is used). |
| 31 | + |
| 32 | +The easiest way to work with a `ReactiveRedisConnectionFactory` is to configure the appropriate connector through the IoC container and inject it into the using class. |
| 33 | + |
| 34 | +[[redis:reactive:connectors:lettuce]] |
| 35 | +=== Configuring Lettuce connector |
| 36 | + |
| 37 | +https://github.com/lettuce-io/lettuce-core[Lettuce] is a http://netty.io/[netty]-based open-source connector supported by Spring Data Redis through the `org.springframework.data.redis.connection.lettuce` package. |
| 38 | + |
| 39 | +Its configuration is probably easy to guess: |
| 40 | + |
| 41 | +[source,java] |
| 42 | +---- |
| 43 | +@Bean |
| 44 | +public ReactiveRedisConnectionFactory lettuceConnectionFactory() { |
| 45 | + return new LettuceConnectionFactory("localhost", 6379); |
| 46 | +} |
| 47 | +---- |
| 48 | + |
| 49 | +A more sophisticated configuration could look like: |
| 50 | + |
| 51 | +[source,java] |
| 52 | +---- |
| 53 | +@Bean |
| 54 | +public ReactiveRedisConnectionFactory lettuceConnectionFactory() { |
| 55 | +
|
| 56 | + RedisStandaloneConfiguration standalone = new RedisStandaloneConfiguration("localhost", 6379); |
| 57 | +
|
| 58 | + LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() |
| 59 | + .useSsl().and() |
| 60 | + .commandTimeout(Duration.ofSeconds(2)) |
| 61 | + .shutdownTimeout(Duration.ZERO) |
| 62 | + .build(); |
| 63 | +
|
| 64 | + return new LettuceConnectionFactory(standalone, clientConfig); |
| 65 | +} |
| 66 | +---- |
| 67 | + |
| 68 | +There are also a few Lettuce-specific connection parameters that can be tweaked. See `LettuceClientConfiguration` for more details. |
| 69 | + |
| 70 | +[[redis:reactive:template]] |
| 71 | +== Working with Objects through ReactiveRedisTemplate |
| 72 | + |
| 73 | +Most users are likely to use `ReactiveRedisTemplate` and its corresponding package `org.springframework.data.redis.core` - the template is in fact the central class of the Redis module due to its rich feature set. The template offers a high-level abstraction for Redis interactions. While `ReactiveRedisConnection` offers low level methods that accept and return binary values (`ByteBuffer`), the template takes care of serialization and connection management, freeing the user from dealing with such details. |
| 74 | + |
| 75 | +Moreover, the template provides operations views (following the grouping from Redis command http://redis.io/commands[reference]) that offer rich, generified interfaces for working against a certain type as described below: |
| 76 | + |
| 77 | +.Operational views |
| 78 | +[width="80%",cols="<1,<2",options="header"] |
| 79 | +|==== |
| 80 | +|Interface |
| 81 | +|Description |
| 82 | + |
| 83 | +2+^|_Key Type Operations_ |
| 84 | + |
| 85 | +|ReactiveGeoOperations |
| 86 | +|Redis geospatial operations like `GEOADD`, `GEORADIUS`,...) |
| 87 | + |
| 88 | +|ReactiveHashOperations |
| 89 | +|Redis hash operations |
| 90 | + |
| 91 | +|ReactiveHyperLogLogOperations |
| 92 | +|Redis HyperLogLog operations like (`PFADD`, `PFCOUNT`,...) |
| 93 | + |
| 94 | +|ReactiveListOperations |
| 95 | +|Redis list operations |
| 96 | + |
| 97 | +|ReactiveSetOperations |
| 98 | +|Redis set operations |
| 99 | + |
| 100 | +|ReactiveValueOperations |
| 101 | +|Redis string (or value) operations |
| 102 | + |
| 103 | +|ReactiveZSetOperations |
| 104 | +|Redis zset (or sorted set) operations |
| 105 | +|==== |
| 106 | + |
| 107 | +Once configured, the template is thread-safe and can be reused across multiple instances. |
| 108 | + |
| 109 | +Out of the box, `ReactiveRedisTemplate` uses a Java-based serializer for most of its operations. This means that any object written or read by the template will be serialized/deserialized through Java throug `RedisElementWriter` respective `RedisElementReader`. The serialization context is passed to the template upon construction, and the Redis module offers several implementations available in the `org.springframework.data.redis.serializer` package - see <<redis:serializer>> for more information. |
| 110 | + |
| 111 | +[source,java] |
| 112 | +---- |
| 113 | +@Configuration |
| 114 | +class RedisConfiguration { |
| 115 | +
|
| 116 | + @Bean |
| 117 | + ReactiveRedisTemplate<String, String> reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) { |
| 118 | + return new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.string()); |
| 119 | + } |
| 120 | +} |
| 121 | +---- |
| 122 | + |
| 123 | +[source,java] |
| 124 | +---- |
| 125 | +public class Example { |
| 126 | +
|
| 127 | + // inject the actual template |
| 128 | + @Autowired |
| 129 | + private ReactiveRedisTemplate<String, String> template; |
| 130 | +
|
| 131 | +
|
| 132 | + public Mono<Long> addLink(String userId, URL url) { |
| 133 | + return template.opsForList().leftPush(userId, url.toExternalForm()); |
| 134 | + } |
| 135 | +} |
| 136 | +---- |
| 137 | + |
| 138 | + |
0 commit comments