Spring Data Redis Reactiveの紹介

Spring Data Redis Reactiveの紹介

1. 前書き

このチュートリアルでは、we’re going to learn how to configure and implement Redis operations using Spring Data’s ReactiveRedisTemplate. 

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

基本をカバーするには、Introduction to Spring Data Redisを確認してください。

2. セットアップ

コードでReactiveRedisTemplate を使用するには、まず、dependency for Spring Boot’s Redis Reactiveモジュールを追加する必要があります。


    org.springframework.boot
    spring-boot-starter-data-redis-reactive

3. 設定

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

しかし、if our server were remote or were on a different port, we could supply the hostname and port in the LettuceConnectionFactory constructor:

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

4. リスト操作

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

4.1. 文字列テンプレート

リストを操作するには、ReactiveRedisTemplate that we’ve provided a String serialization contextのインスタンスが必要です。

@Bean
public ReactiveRedisTemplate reactiveRedisTemplateString
  (ReactiveRedisConnectionFactory connectionFactory) {
    return new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.string());
}

そして、作成したばかりのStringテンプレートから、ReactiveListOperationsのインスタンスを取得できます。

@Autowired
private ReactiveRedisTemplate redisTemplate;

private ReactiveListOperations reactiveListOps;

@Before
public void setup() {
    reactiveListOps = redisTemplate.opsForList();
}

4.2. LPUSHとLPOP

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

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

@Test
public void givenListAndValues_whenLeftPushAndLeftPop_thenLeftPushAndLeftPop() {
    Mono lPush = reactiveListOps.leftPushAll(LIST_NAME, "first", "second")
      .log("Pushed");

    StepVerifier.create(lPush)
      .expectNext(2L)
      .verifyComplete();

    Mono lPop = reactiveListOps.leftPop(LIST_NAME)
      .log("Popped");

    StepVerifier.create(lPop)
      .expectNext("second")
      .verifyComplete();
}

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

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

文字列だけでなく、カスタムオブジェクトも使用できます。

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

public class Employee implements Serializable {
    private String id;
    private String name;
    private String department;

    // ... getters and setters

    // ... hashCode and equals
}

5.1. 従業員テンプレート

ReactiveRedisTemplate.の2番目のインスタンスを作成する必要があります。キーには引き続きString を使用しますが、今回は値はEmployeeになります。

@Bean
public ReactiveRedisTemplate reactiveRedisTemplate(
  ReactiveRedisConnectionFactory factory) {

    StringRedisSerializer keySerializer = new StringRedisSerializer();
    Jackson2JsonRedisSerializer valueSerializer =
      new Jackson2JsonRedisSerializer<>(Employee.class);
    RedisSerializationContext.RedisSerializationContextBuilder builder =
      RedisSerializationContext.newSerializationContext(keySerializer);
    RedisSerializationContext context =
      builder.value(valueSerializer).build();

    return new ReactiveRedisTemplate<>(factory, context);
}

カスタムオブジェクトを正しくシリアル化するには、Springにその方法を指示する必要があります。 ここでは、テンプレートにuse the Jackson library by configuring a Jackson2JsonRedisSerializer for the valueを指示しました。 キーは単なる文字列であるため、StringRedisSerializer を使用できます。

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

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

@Autowired
private ReactiveRedisTemplate redisTemplate;

private ReactiveValueOperations reactiveValueOps;

@Before
public void setup() {
    reactiveValueOps = redisTemplate.opsForValue();
}

5.2. 保存および取得操作

ReactiveValueOperations, letのインスタンスができたので、それを使用してEmployeeのインスタンスを保存します。

@Test
public void givenEmployee_whenSet_thenSet() {

    Mono result = reactiveValueOps.set("123",
      new Employee("123", "Bill", "Accounts"));

    StepVerifier.create(result)
      .expectNext(true)
      .verifyComplete();
}

そして、Redisから同じオブジェクトを取得できます。

@Test
public void givenEmployeeId_whenGet_thenReturnsEmployee() {

    Mono fetchedEmployee = reactiveValueOps.get("123");

    StepVerifier.create(fetchedEmployee)
      .expectNext(new Employee("123", "Bill", "Accounts"))
      .verifyComplete();
}

5.3. 有効期限のある操作

多くの場合、put values in a cache that will naturally expireが必要ですが、同じset 操作でこれを行うことができます。

@Test
public void givenEmployee_whenSetWithExpiry_thenSetsWithExpiryTime()
  throws InterruptedException {

    Mono result = reactiveValueOps.set("129",
      new Employee("129", "John", "Programming"),
      Duration.ofSeconds(1));

    StepVerifier.create(result)
      .expectNext(true)
      .verifyComplete();

    Thread.sleep(2000L);

    Mono fetchedEmployee = reactiveValueOps.get("129");
    StepVerifier.create(fetchedEmployee)
      .expectNextCount(0L)
      .verifyComplete();
}

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

6. Redisコマンド

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

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

ただし、if we want to use the Redis command primitives more directly, then Spring Data Redis Reactive also gives us a Commands API.

それでは、CommandsAPIのレンズを通してStringコマンドとKeyコマンドを見てみましょう。

6.1. 文字列およびキーコマンド

Redisコマンド操作を実行するために、ReactiveKeyCommandsReactiveStringCommands.のインスタンスを取得します

両方を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回の呼び出しbasically invoking the SET command multiple timesで複数のキーを格納できます。

そして、ReactiveKeyCommandsinvoking the KEYS commandを介してこれらのキーを取得できます。

@Test
public void givenFluxOfKeys_whenPerformOperations_thenPerformOperations() {
    Flux 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 keyCount = keyCommands.keys(ByteBuffer.wrap("key*".getBytes()))
      .flatMapMany(Flux::fromIterable)
      .count();

    StepVerifier.create(keyCount)
      .expectNext(4L)
      .verifyComplete();
}

前述のように、このAPIははるかに低レベルであることに注意してください。 たとえば、instead of dealing with high-level objects, we are sending a stream of bytes, using ByteBufferです。 また、SETやSCANなどのRedisプリミティブをより多く使用します。

最後に、文字列コマンドとキーコマンドは、反応的にmany command interfaces that Spring Data Redis exposesの2つにすぎません。

7. 結論

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

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