redis 冗長化&フェールオーバ環境の構築(redis-sentinel setup)

redis 冗長化&自動フェールオーバ環境の構築
redis を複数インスタンス起動させ、レプリケーション(データ同期)させます
フェールオーバには redis-sentinel を採用し master の異常検知で自動に切り替えます
redis-sentinel は、redis 2.4.16 または 2.6.0-rc6 以降のバージョンから利用できます
こちらの 公式ドキュメント も参考にしてください

 
redis 冗長化環境の概要
今回は、 redis を3インスタンス立ち上げ、
1インスタンスを master(読み書き可)、残りを slave(参照のみ)とするケースにしています。

また死活監視には redis-sentinel を利用し、
master に異常を検知したら slave を master に切り替えます

誤った master 昇格を防ぐ目的に、sentinelも 3インスタンス立ち上げます
(3インスタンス中2インスタンスの異常判定でフェールオーバさせます)

なお、混乱を避けるため先に導入した redis は利用せず、すべて新規インスタンスで構築しています

こんな感じです

redis_port

redis 設定ファイル
1インスタンスごとに設定ファイルが必要です
 初期導入した redis 設定ファイルをコピーして利用します

$ sudo cp -p /etc/redis/redis.conf /etc/redis/redis_1.conf
$ sudo cp -p /etc/redis/redis.conf /etc/redis/redis_2.conf
$ sudo cp -p /etc/redis/redis.conf /etc/redis/redis_3.conf

 インスタンスごとにポート、ログファイル、データファイルなどを変更していきます

 redis_1.conf

pidfile /var/run/redis/redis_1.pid
port 6381
logfile "/var/log/redis/redis_1.log"
dbfilename "dump_redis_1.rdb"

 redis_2.conf

pidfile /var/run/redis/redis_2.pid
port 6382
logfile "/var/log/redis/redis_2.log"
dbfilename "dump_redis_2.rdb"

 redis_3.conf

pidfile /var/run/redis/redis_3.pid
port 6383
logfile "/var/log/redis/redis_3.log"
dbfilename "dump_redis_3.rdb"

 
redis の起動スクリプトの準備
こちらも、先にインストールした redis 起動スクリプトをコピーして利用します
なお各OSで起動スクリプト形式・場所が違うので適宜変更してください

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo cp -p /etc/init.d/redis /etc/init.d/redis_1
$ sudo cp -p /etc/init.d/redis /etc/init.d/redis_2
$ sudo cp -p /etc/init.d/redis /etc/init.d/redis_3

 インスタンスごとのポートとプロセスIDファイルを設定します

 init.d/redis_1

REDISPORT=6381
PIDFILE=/var/run/redis/redis_1.pid
CONF="/etc/redis/redis_1.conf"

 init.d/redis_2

REDISPORT=6382
PIDFILE=/var/run/redis/redis_2.pid
CONF="/etc/redis/redis_2.conf"

 init.d/redis_3

REDISPORT=6383
PIDFILE=/var/run/redis/redis_3.pid
CONF="/etc/redis/redis_3.conf"

 Debian/Ubuntu 系の場合は、各インスタンスに合わせ Provides で名前も変更してください

# Provides: redis_N

 [CentOS 7]
 自動起動方式が CentOS 7 以降、変更されています

$ sudo cp -p /usr/lib/systemd/system/redis.service /usr/lib/systemd/system/redis_1.service
$ sudo cp -p /usr/lib/systemd/system/redis.service /usr/lib/systemd/system/redis_2.service
$ sudo cp -p /usr/lib/systemd/system/redis.service /usr/lib/systemd/system/redis_3.service

 redis_1.service

ExecStart=/usr/bin/redis-server /etc/redis/redis_1.conf --daemonize no

 redis_2.service

ExecStart=/usr/bin/redis-server /etc/redis/redis_2.conf --daemonize no

 redis_3.service

ExecStart=/usr/bin/redis-server /etc/redis/redis_3.conf --daemonize no

 
redis の自動起動(サービス)登録と起動確認
redis をサービスとして登録し、起動を確認します

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo chkconfig redis_1 on
$ sudo chkconfig redis_2 on
$ sudo chkconfig redis_3 on

$ sudo /etc/init.d/redis_1 start
$ sudo /etc/init.d/redis_2 start
$ sudo /etc/init.d/redis_3 start

 [CentOS 7]

$ sudo systemctl enable redis_1.service
$ sudo systemctl enable redis_2.service
$ sudo systemctl enable redis_3.service

$ sudo systemctl start redis_1.service
$ sudo systemctl start redis_2.service
$ sudo systemctl start redis_3.service

 CentOS 7で、以下メッセージが表示された場合はクリーンを実行してください
 Warning: Unit file of redis_1.service changed on disk, 'systemctl daemon-reload' recommended.

$ sudo systemctl daemon-reload

 
redis の実行プロセスが表示されることを確認します

 インストールしたパス(/usr/bin, /usr/sbin もしくは /usr/local/bin)で起動されてます

$ ps -ef | grep redis
root 1593 1 0 15:50 ? 00:00:08 /usr/bin/redis-server 127.0.0.1:6381
root 1594 1 0 15:50 ? 00:00:08 /usr/bin/redis-server 127.0.0.1:6382
root 1595 1 0 15:50 ? 00:00:08 /usr/bin/redis-server 127.0.0.1:6383

 ログファイルが作成されていることを確認します

$ ls -l /var/log/redis/
-rw-r--r-- 1 redis redis 36860 11月 18 08:17 2015 redis.log
-rw-r--r-- 1 root root 36860 11月 19 13:07 2015 redis_1.log
-rw-r--r-- 1 root root 20085 11月 19 13:07 2015 redis_2.log
-rw-r--r-- 1 root root 23153 11月 19 13:07 2015 redis_3.log

 プロセスファイル/ダンプファイルが作成されていることを確認します

$ ls -l /var/run/redis/
-rw-r--r-- 1 root root 18 11月 18 08:17 2015 dump_redis.rdb
-rw-r--r-- 1 root root 18 11月 19 21:15 2015 dump_redis_1.rdb
-rw-r--r-- 1 root root 18 11月 19 21:15 2015 dump_redis_2.rdb
-rw-r--r-- 1 root root 18 11月 19 21:15 2015 dump_redis_3.rdb
-rw-r--r-- 1 root root 5 11月 18 08:17 2015 redis.pid
-rw-r--r-- 1 root root 5 11月 19 21:15 2015 redis_1.pid
-rw-r--r-- 1 root root 5 11月 19 21:15 2015 redis_2.pid
-rw-r--r-- 1 root root 5 11月 19 21:15 2015 redis_3.pid

すべての redis インスタンスに接続できることを確認します
この時点では、すべてのインスタンスが master で起動されています

 redis_1の確認

$ redis-cli -p 6381 info | egrep 'role|port'
tcp_port:6381
role:master

 redis_2の確認

$ redis-cli -p 6382 info | egrep 'role|port'
tcp_port:6382
role:master

 redis_3の確認

$ redis-cli -p 6383 info | egrep 'role|port'
tcp_port:6383
role:master

 
redis 冗長化の確認
2インスタンスを slave モードに切り替えて、redis が冗長化されるか確認します

 6382/6383ポートの redis を slave に切り替えます

$ redis-cli -p 6382 slaveof 127.0.0.1 6381
$ redis-cli -p 6383 slaveof 127.0.0.1 6381

 正しく slave に切り替えられたか確認します
 6381 が role:master、その他が role:slave でレスポンスされていることを確認します

$ redis-cli -p 6381 info | grep role
role:master
$ redis-cli -p 6382 info | grep role
role:slave
$ redis-cli -p 6383 info | grep role
role:slave

 master に値をセットし、slave 側へ反映されることを確認します

$ redis-cli -p 6381 set hoge on
OK
$ redis-cli -p 6382 get hoge
"on"
$ redis-cli -p 6383 get hoge
"on"

$ redis-cli -p 6381 del hoge
(integer) 1
$ redis-cli -p 6382 get hoge
(nil)
$ redis-cli -p 6383 get hoge
(nil)

 
 
フェールオーバ環境の構築
さて、ここからが自動フェールオーバーの構築になります
redis-sentinel を利用して redis のフェールオーバ設定をおこないます

redis-sentinel のインストール
redis をパッケージ導入した場合は、
redis-sentinel も一緒にインストールされるため次の章に進んで構いません

 ソースから導入した場合は、
 以下のように redis-2.8.*/src 配下の redis-sentinel (バイナリファイル)をコピーします

$ sudo cp -p ./redis-2.8.*/src/redis-sentinel /usr/local/bin/

 
redis-sentinel の設定ファイル
こちらも、各インスタンスごとに設定ファイルが必要です
既存の redis-sentinel 設定ファイルをコピーし、各インスタンス用に起動ポートなどを変更します

 [ソースインストール]
 展開したソース配下にある既存の設定ファイルをコピーして利用します

$ sudo cp -p ./redis-2.8.*/sentinel.conf /etc/redis/sentinel_1.conf

 [パッケージインストール]
 インストールされた既存の設定ファイルを探してコピーします

$ locate sentinel.conf
/etc/redis/sentinel.conf
$ sudo cp -p /etc/redis/sentinel.conf /etc/redis/sentinel_1.conf

 
起動ポートとフェールオーバの設定をおこないます
以下例は、5秒間 master が応答がなければ slave を master に昇格させる設定となります
また、(別筐体のサーバで)分散稼働させる場合は IPアドレス/ポート を適切な値に置き換えることが必要です

$ sudo vi /etc/redis/sentinel_1.conf
daemonize yes
port 26381
sentinel monitor mymaster 127.0.0.1 6381 2
sentinel down-after-milliseconds mymaster 5000

 上記の ”sentinel monitor mymaster 127.0.0.1 6381 2” の最後尾に記述している
 ”2″ の値が、3インスタンス中の2インスタンス(=多数決)で判定する閾値となります

 もし sentinel を5インスタンス稼働させ、うち3インスタンスで判定する場合は “3” と設定します

 
 作成した設定ファイルをコピーします

$ sudo cp -p /etc/redis/sentinel_1.conf /etc/redis/sentinel_2.conf
$ sudo cp -p /etc/redis/sentinel_1.conf /etc/redis/sentinel_3.conf

 2インスタンス用にポートを変更します

$ sudo vi /etc/redis/sentinel_2.conf
port 26382

 3インスタンス用にポートを変更します

$ sudo vi /etc/redis/sentinel_3.conf
port 26383

redis-sentinel は稼働中、redis 設定ファイルに書き込みをおこないます
所有オーナーと書き込み権限を変更しておきます

$ sudo chmod 644 /etc/redis/sentinel_1.conf
$ sudo chmod 644 /etc/redis/sentinel_2.conf
$ sudo chmod 644 /etc/redis/sentinel_3.conf
$ sudo chown redis:redis /etc/redis/sentinel_1.conf
$ sudo chown redis:redis /etc/redis/sentinel_2.conf
$ sudo chown redis:redis /etc/redis/sentinel_3.conf

 
redis-sentinel の起動スクリプトの準備
自動起動用のスクリプトファイルを用意します

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo cp -p /etc/init.d/redis-server-1 /etc/init.d/redis-sentinel-1

 [CentOS 7]

$ sudo cp -p /usr/lib/systemd/system/redis-sentinel.service /usr/lib/systemd/system/redis-sentinel-1.service

 各OSに対応する起動ファイルの設定をおこないます

 [CentOS 5/6]
 init.d/redis-sentinel-1

# chkconfig: 345 85 15
# description: sentinel-1
# processname: sentinel-1
# pidfile: /var/run/redis/sentinel-1.pid
# config: /etc/redis/sentinel-1.conf
name="sentinel-1"
pidfile="/var/run/redis/sentinel-1.pid"
REDIS_CONFIG="/etc/redis/sentinel-1.conf"
[ -e /etc/sysconfig/redis-sentinel ] && . /etc/sysconfig/redis-sentinel

 [CentOS 7]
 redis-sentinel-1.service

ExecStart=/usr/bin/redis-sentinel /etc/redis/sentinel-1.conf --daemonize no
ExecStop=/usr/bin/redis-shutdown sentinel-1

 [Debian6/7, Ubuntu]
 init.d/redis-sentinel-1

### BEGIN INIT INFO
# Provides: redis-sentinel-1
# Required-Start: $syslog $remote_fs bootlogs
# Required-Stop: $syslog $remote_fs
# Should-Start: $local_fs
# Should-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Redis Sentinel is a KVS server.
# Short-Description: sentinel-1
### END INIT INFO
DAEMON=/usr/local/bin/redis-sentinel
DAEMON_ARGS=/etc/redis/sentinel-1.conf
NAME=sentinel-1
DESC=sentinel-1
PIDFILE=$RUNDIR/redis-sentinel-1.pid

 
redis-sentinel の起動確認
起動スクリプトで redis-sentinel−1 を起動します

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo /etc/init.d/redis-sentinel-1 start

 [CentOS 7]

$ sudo systemctl start redis-sentinel-1.service

 起動を確認します

$ ps -ef | grep redis-sentinel
redis 1679 1 0 19:38 ? 00:00:18 /usr/bin/redis-sentinel *:26381

 起動確認できたら起動ファイルをコピーし、残りのインスタンス分を用意します

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo cp -p /etc/init.d/redis-sentinel-1 /etc/init.d/redis-sentinel-2
$ sudo cp -p /etc/init.d/redis-sentinel-1 /etc/init.d/redis-sentinel-3

 [CentOS 7]

$ sudo cp -p /usr/lib/systemd/system/redis-sentinel-1.service /usr/lib/systemd/system/redis-sentinel-2.service
$ sudo cp -p /usr/lib/systemd/system/redis-sentinel-1.service /usr/lib/systemd/system/redis-sentinel-3.service

 各インスタンス用に起動ファイルを変更します
 sentinel-1 と記載されている箇所を、すべて sentinel-2(またはsentinel-3)に変更します

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo vi /etc/init.d/redis-sentinel-2
:%s/sentinel_1/sentinel_2/g
$ sudo vi /etc/init.d/redis-sentinel-3
:%s/sentinel_1/sentinel_3/g

 [CentOS 7]

$ sudo vi /usr/lib/systemd/system/redis-sentinel-2.service
:%s/sentinel_1/sentinel_2/g
$ sudo vi /usr/lib/systemd/system/redis-sentinel-3.service
:%s/sentinel_1/sentinel_3/g

 起動スクリプトで redis-sentinel-2/3 を起動します

 [CentOS 5/6, Debian6/7, Ubuntu]

$ sudo /etc/init.d/redis-sentinel-2 start
$ sudo /etc/init.d/redis-sentinel-3 start

 [CentOS 7]

$ sudo systemctl start redis-sentinel-2.service
$ sudo systemctl start redis-sentinel-3.service

 起動を確認します

$ ps -ef | grep redis-sentinel
redis 1679 1 0 19:38 ? 00:00:18 /usr/bin/redis-sentinel *:26381
redis 1694 1 0 19:38 ? 00:00:18 /usr/bin/redis-sentinel *:26382
redis 1708 1 0 19:38 ? 00:00:17 /usr/bin/redis-sentinel *:26383

 
redis-sentinel の動作確認
master を終了させ、自動で slave が master に昇格されることを確認します

現在のステータスを確認します
ポート6381が master 、その他が slave となっています

$ redis-cli -p 6381 info | grep role
role:master
$ redis-cli -p 6382 info | grep role
role:slave
$ redis-cli -p 6383 info | grep role
role:slave

 master を終了させ、5秒後に slave が master に昇格されることを確認します

$ redis-cli -p 6381 shutdown

 5秒ほど待ってから

$ redis-cli -p 6381 info | grep role
Could not connect to Redis at 127.0.0.1:6381: Connection refused
$ redis-cli -p 6382 info | grep role
role:master
$ redis-cli -p 6383 info | grep role
role:slave

 ポート6381を再度起動させ slave で起動されることを確認します

$ sudo /etc/init.d/redis-server-1 start

 5秒以上経過してから

$ redis-cli -p 6381 info | grep role
role:slave
$ redis-cli -p 6382 info | grep role
role:master
$ redis-cli -p 6383 info | grep role
role:slave

 
redis-sentinel の自動起動設定
サーバの再起動でも自動でサービス起動、停止するようにします

 [CentOS 5/6]

$ sudo chkconfig redis-sentinel-1 on
$ sudo chkconfig redis-sentinel-2 on
$ sudo chkconfig redis-sentinel-3 on
$ chkconfig --list | grep redis

 [CentOS 7]

$ sudo systemctl enable redis-sentinel-1.service
$ sudo systemctl enable redis-sentinel-2.service
$ sudo systemctl enable redis-sentinel-3.service
$ sudo systemctl list-unit-files | grep redis

 [Debian6/7, Ubuntu]

$ sudo sysv-rc-conf redis-sentinel-1 on
$ sudo sysv-rc-conf redis-sentinel-2 on
$ sudo sysv-rc-conf redis-sentinel-3 on
$ sysv-rc-conf --list | grep redis

 
redis/redus-sentinel の自動起動確認
 サーバを再起動させ、redis 及び redis-sentinel が自動起動されることを確認します

$ sudo shutdown -r now

 サーバ再起動後、

$ ps -ef | grep redis
redis 1593 1 0 18:08 ? 00:00:24 /usr/bin/redis-server 127.0.0.1:6381
redis 1594 1 0 18:08 ? 00:00:24 /usr/bin/redis-server 127.0.0.1:6382
redis 1595 1 0 18:08 ? 00:00:24 /usr/bin/redis-server 127.0.0.1:6383
redis 1601 1 0 18:08 ? 00:00:38 /usr/bin/redis-sentinel *:26381
redis 1602 1 0 18:08 ? 00:00:38 /usr/bin/redis-sentinel *:26382
redis 1604 1 0 18:08 ? 00:00:42 /usr/bin/redis-sentinel *:26383

再起動されていることを確認で終了です

コメントを残す

メールアドレスが公開されることはありません。