LoginSignup
13
11

More than 5 years have passed since last update.

Spring Data RedisでRedis Sentinelを利用する

Last updated at Posted at 2015-09-19

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

スクリーンショット 2015-09-13 17.24.29.png

利用方法

  • 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を利用した状態で確認する。
流れを簡単に図示すると以下のようになる。

スクリーンショット 2015-09-13 20.33.01.png

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から実施したい場合には自作する必要がある。

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11