Spring BootのRedisキャッシュで、Master/Replicaを呼び分ける方法

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

アドベントカレンダーも14日目となり、中盤を過ぎてきました。 今回はRedisとSpring Bootの話になります。

Redisの可用性を高めるために有用な手段ですので、参考にしていただければ幸いです。

はじめに

Redisでは、同じデータに対して、書き込み・読み込みが両方可能なMasterと、読み込み専用のReplicaを別々に設定することができます。 Masterを基本的に書き込み専用に、Replicaを読み込み専用に使用することで、可用性を高くすることができます。

今回は、そのような構成になっているRedisをキャッシュとして使う際に、Spring Bootでどのように呼び分けるかを解説していきます。

RedisのMaster/Replica

Redisは、オンメモリのkey-valueなデータベースです。 MySQLなどに比べて非常に高速で、一方でリレーショナルではないため、複雑なデータ結合が不要なキャッシュなどで使用されることが多いアプリケーションとなっています。

非常に高速とはいえ、もちろん負荷が高まればアクセスを捌ききれなくなることもあります。 その際、いくつか対応方法があります。

スペックを上げる

Redisに使用するサーバ等のCPUスペックやメモリサイズを上げることで、Redisが捌けるアクセス数を増やすことができます。

数を増やす

Redisを動かしているサーバ等の数を増やすことで、1台あたりのアクセス数を減らし、結果としてRedis全体が捌けるアクセス数を増やすことができます。

どちらにするかはその時々ですが、「数を増やす」対応だと、例えば1台落ちたときに他で対応できたりなど可用性が高まりやすい利点があります。 一方でデータに不整合が出ないよう、「1台のみの書き込み・読み込み両用のMaster」と「1台以上の読み込み専用のReplica」を用意し、書き込みはMasterで、読み込みは基本的にReplicaで行うようにするため、呼び分けをする必要が出てきます。

Spring Bootでは、次の方法で呼び分けることができます。

Spring Bootでの呼び分け方法

基本的なRedisキャッシュの設定に以下の設定を加えれば、Master/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 {
    /**
     * Redis接続用設定のFactory
     *
     * @return Lettuce接続用設定のFactory
     */
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        // 環境ごとに値が違う場合は、application.yml等を使って分けてください
        String masterHost = "masterHost";
        Integer masterPort = 6379;
        String replicaHost = "replicaHost";
        Integer replicaPort = 6379;
        Integer database = 0;

        // ReadFromには他にもいくつかタイプがあるので、適したものを指定してください
        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)
                .build();

        // Amazon ElasticacheではRedisStaticMasterReplicaConfigurationが適していますが、構成によってはRedisStandaloneConfigurationが適している場合もあります
        // LINK: https://spring.pleiades.io/spring-data/redis/docs/current/reference/html/#redis:write-to-master-read-from-replica
        RedisStaticMasterReplicaConfiguration serverConfig = new RedisStaticMasterReplicaConfiguration(masterHost, masterPort);
        serverConfig.addNode(replicaHost, replicaPort);
        serverConfig.setDatabase(database);

        return new LettuceConnectionFactory(serverConfig, clientConfig);
    }
}

基本的にはこれだけで、キャッシュに書き込む時はMaster経由で、キャッシュから読み込む時はReplica経由で、それぞれアクセスできるようになります。

最後に

Redisを複数台で動かすことは、可用性を高めるために非常に有効な手の1つです。 Spring Bootの場合は上記の方法で簡単に呼び分けができるようになるので、ぜひ試してみてください。


アドベントカレンダーはまだまだ続きます! 明日以降も見ていっていただけると幸いです!

qiita.com