Spring BootにおけるRedisのPrimary/Replicaノード判定が自動だったという話

こんにちは。 エキサイト株式会社の三浦です。

以前、Spring Bootにおいて、RedisのPrimary(Master)とReplicaのノードをそれぞれ呼び分けて使うことができる、という記事を書きました。

tech.excite.co.jp

今回はそれに関連して、実はPrimaryノード・Replicaノードの判定が、「コードでの追加順」ではなく「自動」だったというお話をしていきます。

Spring Bootにおける、RedisのPrimary / Replicaノードの呼び分け

Spring Bootでは、Redisを使う際に Primary / Replicaノードを以下のコードで呼び分けることができます。

package sample;

import io.lettuce.core.ReadFrom;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {

        // Primaryノードの設定
        String primaryHost = "localhost";
        Integer primaryPort = 63791;

        // Replicaノードの設定
        String replicaHost = "localhost";
        Integer replicaPort = 63792;

        Integer database = 0;

        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)
                .build();

        RedisStaticMasterReplicaConfiguration serverConfig = new RedisStaticMasterReplicaConfiguration(primaryHost, primaryPort);
        serverConfig.addNode(replicaHost, replicaPort);
        serverConfig.setDatabase(database);

        return new LettuceConnectionFactory(serverConfig, clientConfig);
    }
}

詳しくは、以前書いた以下の記事を御覧ください。

tech.excite.co.jp

これを実行すると、実際の設定値は以下のようになっています。

想定通り、 port: 63791 のノードがPrimary、 port: 63792 のノードがReplicaとして判定されていることがわかります。

ここで一つの疑問が生じました。

このPrimaryとReplicaの判定は、コードでの追加順で決まるのでしょうか?

PrimaryとReplicaの判定は自動的に行われる

それでは今度は、追加順を逆にしてみましょう。

package sample;

import io.lettuce.core.ReadFrom;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;

@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {

        // Primaryノードの設定
        String primaryHost = "localhost";
        Integer primaryPort = 63791;

        // Replicaノードの設定
        String replicaHost = "localhost";
        Integer replicaPort = 63792;

        Integer database = 0;

        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)
                .build();

        // 追加順を逆にしてみる
        RedisStaticMasterReplicaConfiguration serverConfig = new RedisStaticMasterReplicaConfiguration(replicaHost, replicaPort);
        serverConfig.addNode(primaryHost, primaryPort);
        serverConfig.setDatabase(database);

        return new LettuceConnectionFactory(serverConfig, clientConfig);
    }
}

結果はこうなります。

ノードの追加順を変更したことでリストの要素の順番は変わっていますが、なんとPrimary / Replica判定は正しく行われています!

このことから、ノードの追加順でPrimary / Replicaが判定されているのではなく、実際にノードの内容から自動的にPrimary / Replicaの判定がされていることがわかりました。

最後に

自動的に判定が行われるということで、アプリケーション開発者としては気にしなければいけないことが一つ減り、良いことなのではないかなと思います。

負荷の分散という意味でノードを分けることは非常に効果的なので、ぜひやってみてください!