1. 序章

このチュートリアルでは、 Spring DataのReactiveRedisTemplateを使用してRedis操作を構成および実装する方法を学習します。 

ReactiveRedisTemplate の基本的な使用法(Redisでオブジェクトを保存および取得する方法など)について説明します。 そして、ReactiveRedisConnectionを使用してRedisコマンドを実行する方法を見ていきます。

基本をカバーするために、 SpringDataRedisの紹介をチェックしてください。

2. 設定

コードでReactiveRedisTemplateを使用するには、まず、Spring BootのRedisReactiveモジュールの依存関係を追加する必要があります。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

3. 構成

次に、Redisサーバーとの接続を確立する必要があります。 localhost:6379 のRedisサーバーに接続する場合は、構成用のコードを追加する必要はありません。

ただし、サーバーがリモートであるか、別のポートにある場合は、LettuceConnectionFactoryコンストラクターでホスト名とポートを指定できます:

@Bean
public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
    return new LettuceConnectionFactory(host, port);
}

4. リスト操作

Redisリストは、挿入順序でソートされた文字列のリストです。 要素を左または右からプッシュまたはポップすることで、リストに要素を追加またはリストから削除できます。

4.1. 文字列テンプレート

リストを操作するには、ReactiveStringRedisTemplateのインスタンスを使用してRedisListOperationsへの参照を取得する必要があります。

@Autowired
private ReactiveStringRedisTemplate redisTemplate;
private ReactiveListOperations<String, String> reactiveListOps;
@Before
public void setup() {
    reactiveListOps = redisTemplate.opsForList();
}

4.2. LPUSHとLPOP

ReactiveListOperationsのインスタンスができたので、リストの識別子としてdemo_listを使用してリストに対してLPUSH操作を実行してみましょう。

その後、リストでLPOPを実行し、ポップされた要素を確認します。

@Test
public void givenListAndValues_whenLeftPushAndLeftPop_thenLeftPushAndLeftPop() {
    Mono<Long> lPush = reactiveListOps.leftPushAll(LIST_NAME, "first", "second")
      .log("Pushed");
    StepVerifier.create(lPush)
      .expectNext(2L)
      .verifyComplete();
    Mono<String> lPop = reactiveListOps.leftPop(LIST_NAME)
      .log("Popped");
    StepVerifier.create(lPop)
      .expectNext("second")
      .verifyComplete();
}

リアクティブコンポーネントをテストする場合、 StepVerifier を使用して、タスクの完了をブロックできることに注意してください。

5. バリューオペレーション

文字列だけでなく、カスタムオブジェクトも使用したい場合があります。

それでは、POJOでの操作を示すために、Employeeオブジェクトで同様の操作をいくつか実行してみましょう。

public class Employee implements Serializable {
    private String id;
    private String name;
    private String department;
    // ... getters and setters
    // ... hashCode and equals
}

5.1. 従業員テンプレート

次の2番目のインスタンスを作成する必要があります ReactiveRedisTemplate。 引き続き使用しますキーの場合ですが、今回の値は次のようになります従業員

@Bean
public ReactiveRedisTemplate<String, Employee> reactiveRedisTemplate(
  ReactiveRedisConnectionFactory factory) {
    StringRedisSerializer keySerializer = new StringRedisSerializer();
    Jackson2JsonRedisSerializer<Employee> valueSerializer =
      new Jackson2JsonRedisSerializer<>(Employee.class);
    RedisSerializationContext.RedisSerializationContextBuilder<String, Employee> builder =
      RedisSerializationContext.newSerializationContext(keySerializer);
    RedisSerializationContext<String, Employee> context = 
      builder.value(valueSerializer).build();
    return new ReactiveRedisTemplate<>(factory, context);
}

カスタムオブジェクトを正しくシリアル化するには、Springにその方法を指示する必要があります。 ここでは、値 Jackson2JsonRedisSerializer を構成して、Jacksonライブラリを使用するようにテンプレートに指示しました。 キーは単なる文字列なので、StringRedisSerializerを使用できます。

次に、このシリアル化コンテキストと接続ファクトリを使用して、前と同じようにテンプレートを作成します。

次に、 ReactiveListOperations で以前に行ったのと同じように、ReactiveValueOperationsのインスタンスを作成します。

@Autowired
private ReactiveRedisTemplate<String, Employee> redisTemplate;
private ReactiveValueOperations<String, Employee> reactiveValueOps;
@Before
public void setup() {
    reactiveValueOps = redisTemplate.opsForValue();
}

5.2. 保存および取得操作

ReactiveValueOperationsのインスタンスができたので、それを使用してEmployeeのインスタンスを格納しましょう。

@Test
public void givenEmployee_whenSet_thenSet() {
    Mono<Boolean> result = reactiveValueOps.set("123", 
      new Employee("123", "Bill", "Accounts"));
    StepVerifier.create(result)
      .expectNext(true)
      .verifyComplete();
}

そして、Redisから同じオブジェクトを取り戻すことができます。

@Test
public void givenEmployeeId_whenGet_thenReturnsEmployee() {
    Mono<Employee> fetchedEmployee = reactiveValueOps.get("123");
    StepVerifier.create(fetchedEmployee)
      .expectNext(new Employee("123", "Bill", "Accounts"))
      .verifyComplete();
}

5.3. 有効期限のある操作

多くの場合、値をキャッシュに入れて、自然に期限切れになるようにします。これは、同じset操作で実行できます。

@Test
public void givenEmployee_whenSetWithExpiry_thenSetsWithExpiryTime() 
  throws InterruptedException {
    Mono<Boolean> result = reactiveValueOps.set("129", 
      new Employee("129", "John", "Programming"), 
      Duration.ofSeconds(1));
    StepVerifier.create(result)
      .expectNext(true)
      .verifyComplete();
    Thread.sleep(2000L); 
    Mono<Employee> fetchedEmployee = reactiveValueOps.get("129");
    StepVerifier.create(fetchedEmployee)
      .expectNextCount(0L)
      .verifyComplete();
}

このテストは、キャッシュキーの有効期限が切れるのを待つために、独自のブロッキングを行うことに注意してください。

6. Redisコマンド

Redisコマンドは基本的に、Redisクライアントがサーバー上で呼び出すことができるメソッドです。 また、Redisは数十のコマンドをサポートしており、LPUSHやLPOPなど、すでにいくつかのコマンドを確認しています。

Operations APIは、Redisの一連のコマンドに関する高レベルの抽象化です。

ただし、 Redisコマンドプリミティブをより直接的に使用したい場合は、Spring DataRedisReactiveもコマンドAPIを提供します。

それでは、コマンドAPIのレンズを通して文字列コマンドとキーコマンドを見てみましょう。

6.1. 文字列とキーコマンド

Redisコマンド操作を実行するために、ReactionKeyCommandsおよびReactiveStringCommandsのインスタンスを取得します。

両方をReactiveRedisConnectionFactoryインスタンスから取得できます。

@Bean
public ReactiveKeyCommands keyCommands(ReactiveRedisConnectionFactory 
  reactiveRedisConnectionFactory) {
    return reactiveRedisConnectionFactory.getReactiveConnection().keyCommands();
}
@Bean
public ReactiveStringCommands stringCommands(ReactiveRedisConnectionFactory 
  reactiveRedisConnectionFactory) {
    return reactiveRedisConnectionFactory.getReactiveConnection().stringCommands();
}

6.2. 操作の設定と取得

ReactiveStringCommands を使用して、1回の呼び出しで複数のキーを格納できます。基本的にSETコマンドを複数回呼び出します

次に、 ReactiveKeyCommands KEYSコマンドを呼び出して、これらのキーを取得できます。

@Test
public void givenFluxOfKeys_whenPerformOperations_thenPerformOperations() {
    Flux<SetCommand> keys = Flux.just("key1", "key2", "key3", "key4");
      .map(String::getBytes)
      .map(ByteBuffer::wrap)
      .map(key -> SetCommand.set(key).value(key));
    StepVerifier.create(stringCommands.set(keys))
      .expectNextCount(4L)
      .verifyComplete();
    Mono<Long> keyCount = keyCommands.keys(ByteBuffer.wrap("key*".getBytes()))
      .flatMapMany(Flux::fromIterable)
      .count();
    StepVerifier.create(keyCount)
      .expectNext(4L)
      .verifyComplete();
}

前述のように、このAPIははるかに低レベルであることに注意してください。 たとえば、は、高レベルのオブジェクトを処理する代わりに、ByteBufferを使用してバイトのストリームを送信しています。 また、SETやSCANなどのRedisプリミティブをより多く使用しています。

最後に、文字列コマンドとキーコマンドは、SpringDataRedisがリアクティブに公開する多くのコマンドインターフェイスの2つにすぎません

7. 結論

このチュートリアルでは、Spring DataのReactive Redisテンプレートの使用の基本と、それをアプリケーションと統合するためのさまざまな方法について説明しました。

例の完全なソースコードは、GitHubから入手できます。