Edited at

Spring Data RedisでRedis Sentinelを利用する

More than 3 years have passed since last update.

前回はSpring BootとSpring Data Redisを利用してRedisを利用する方法を書いた。

今回はSpring Data RedisをRedis Sentinel構成で利用する方法。


利用方法


  • applicaion.ymlにSentinelの情報を記載する。

spring:

data:
redis:
Sentinel:
master: cluster1
nodes: localhost:26379,localhost:26380,localhost:26381


  • masterプロパティはSentinelに設定したクラスタの名称。
    以下はSentinelのログ、Sentinelで認識しているクラスタの名称と同じにする必要がある。

[1] 13 Sep 07:41:51.043 # Sentinel runid is 2510f2561aff03a249726db05e195efc8ee80920

[1] 13 Sep 07:41:51.046 # +monitor master cluster1 192.168.59.103 6379 quorum 2
[1] 13 Sep 07:41:52.047 * +slave slave 172.17.42.1:6380 172.17.42.1 6380 @ cluster1 192.168.59.103 6379


  • nodesプロパティはSentinelの接続先をカンマ区切りで指定する。

  • Sentinel構成では無い時に指定していたhost/portの設定は不要。

上記の設定だけでSpring Data RedisがSentinelのプロセスからマスターノードの情報を取得するため、Sentinel構成の時でない場合と同様にRedisTemplateを利用してRedisを操作することができる。


Masterの判定方法を追ってみる

次にSpring Data RedisからどのようにしてMasterの情報を取得しているのか確認する。

前提として、Spring Data Redisがデフォルトで利用するRedisのクライアントであるJedisを利用した状態で確認する。

流れを簡単に図示すると以下のようになる。


Sentinelへのコネクションプール生成

Spring Boot起動時など、まずJedisConnectionFactoryがBeanとして初期化されるタイミングで、application.ymlにSentinelの設定がなされていれば、Sentine用のコネクションプールJedisSentinelPoolを作成している。以下はJedisConnectionFactoryのソース一部抜粋。

public void afterPropertiesSet() {

// 略

if (usePool) {
this.pool = createPool();
}
}

private Pool<Jedis> createPool() {

if (isRedisSentinelAware()) {
return createRedisSentinelPool(this.SentinelConfig);
}
return createRedisPool();
}


Masterの判定

JedisSentinelPoolのコンストラクタで以下の処理が行われる。



  • Sentinelに対して順番にMasterが見つかるまで以下のコマンドを発行

    SENTINEL get-master-addr-by-name cluster1
    


  • 一つ以上のSentinelからmasterの情報が取得できなければ例外

    そのため、JedisConnectionFactory初期化のタイミングでは必ず1台のSentinelには接続できなければならない。


  • 見つかったMasterに対してコネクションプールを生成



SentinelへのSubscribe開始

上記と同時にSentinelのプロセス毎にMasterListenerというスレッドを起動する。

MasterListerでそれぞれが担当するSentinelプロセスに対してマスター変更をサブスクライブする。

SUBSCRIBE +switch-master


SentinelによりMasterが変更された時

MasterListenerが新Masterの接続先情報を受け取る。その後JedisSentinelPoolが新Masterに対するコネクションプールを作成する。


障害時の振る舞い


  • Redisのマスターが停止してからSpring Data Redis側でコネクションプールを再生成するまではRedisTemplateでのRedisへのアクセスはエラーとなる。


  • Sentinelが全停止していてもMasterが停止していなければRedisTemplateでエラーになることはない。


  • Sentinelが停止してもMasterListenerはデフォルトで5秒毎に再接続試行しているため、Sentinelを再起動すれば接続が復旧する。



その他

Masterに対してはアクセスできるが、Slaveだけアクセスする仕組みはないため、Read処理をSlaveから実施したい場合には自作する必要がある。