RedisMaster/SlaveとSentinelのインストールのまとめと簡単な動作確認。

ついでに、Vagrantを使って次の構成を作って試してみた。

+-------+-------------------+-------------------+-------+
| | |
+-------+-------+ +-------+-------+ +-------+-------+
| 192.168.33.10 | | 192.168.33.11 | | 192.168.33.12 |
| | | | | |
| redis(master) | | redi(slave) | | redis(slave) |
| sentinel | | sentinel | | sentinel |
+---------------+ +---------------+ +---------------+

環境

  • CentOS7
  • Redis 3.2.4
               _._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 3.2.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 4035
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'

設定

Redis Master/SlaveとSentinelに必要な必要最低限の設定をデフォルトの設定を参考に設定する。

インストールはutils/install_server.shを使った。sentinelの起動スクリプトが含まれていないのでRedisの設定ファイルをコピーして必要な部分を書き換える。

ゴリゴリ書いたVagrantfileは次の通り。

$ mkdir redis3 && cd redis3
$ vagrant init
$ vim Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.vm.provision "shell", inline: <<-SHELL
yum update -y
yum install wget make gcc tcl readline-devel -y
wget http://download.redis.io/releases/redis-3.2.4.tar.gz
tar zxfv redis-3.2.4.tar.gz && cd redis-3.2.4
make && make install
echo -e "\n\n\n\n/usr/local/bin/redis-server\n" | utils/install_server.sh
sleep 1
/etc/init.d/redis_6379 stop
sed -i -e "s/^protected-mode yes$/protected-mode no/g" /etc/redis/6379.conf
sed -i -e "s/^bind 127.0.0.1$/bind 0.0.0.0/g" /etc/redis/6379.conf
cp sentinel.conf /etc/redis/26379.conf
echo "daemonize yes" >> /etc/redis/26379.conf
sed -i -e "s/^# protected-mode no$/protected-mode no/g" /etc/redis/26379.conf
sed -i -e "s/sentinel monitor mymaster 127.0.0.1 6379 2/sentinel monitor mymaster 192.168.33.10 6379 2/g" /etc/redis/26379.conf
cp /etc/init.d/redis_6379 /etc/init.d/sentinel_26379
sed -i -e "s|/usr/local/bin/redis-server|/usr/local/bin/redis-sentinel|g" /etc/init.d/sentinel_26379
sed -i -e 's/6379/26379/g' /etc/init.d/sentinel_26379
SHELL

config.vm.define :node1 do |node|
node.vm.provision :shell, inline: <<-SHELL
/etc/init.d/redis_6379 start
/etc/init.d/sentinel_26379 start
SHELL
node.vm.network :private_network, ip: "192.168.33.10"
node.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
end

config.vm.define :node2 do |node|
node.vm.provision :shell, inline: <<-SHELL
sed -i -e "s/^# slaveof <masterip> <masterport>$/slaveof 192.168.33.10 6379/g" /etc/redis/6379.conf
/etc/init.d/redis_6379 start
/etc/init.d/sentinel_26379 start
SHELL
node.vm.network :private_network, ip: "192.168.33.11"
node.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
end

config.vm.define :node3 do |node|
node.vm.provision :shell, inline: <<-SHELL
sed -i -e "s/^# slaveof <masterip> <masterport>$/slaveof 192.168.33.10 6379/g" /etc/redis/6379.conf
/etc/init.d/redis_6379 start
/etc/init.d/sentinel_26379 start
SHELL
node.vm.network :private_network, ip: "192.168.33.12"
node.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
end

end

install_server.shを実行すると最後にRedisを起動するが、直後にstopすると起動する前にstopしようとしてしまい、pidが無いと言われて正しく動かないのでsleep 1している。

bind 0.0.0.0としているがリッスンするIPを指定したい場合は次の様に書き換えること。

sed -i -e "s/^bind 127.0.0.1$/bind 192.168.33.1X 127.0.0.1/g" /etc/redis/6379.conf

フェイルオーバーはデフォルトでは30秒なので早くしたい場合は次の設定を入れ適切に時間(ms)を設定する。

sentinel down-after-milliseconds mymaster 30000

パスワード認証をする場合は次の設定をする。

sentinel auth-pass mymaster <password>

起動

起動してみる。10分弱かかるので注意。

$ vagrant up

node1がマスターになっているはずなのでnode1にsshする。

$ vagrant ssh node1

確認

redis-cliコマンドで色々確認してみる。

Redis Master/Slaveの確認

Redisのmasterに接続して確認するとmasterであることとスレーブが2台認識されていることが確認できる。

node1$ redis-cli -p 6379 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.33.11,port=6379,state=online,offset=699006,lag=1
slave1:ip=192.168.33.12,port=6379,state=online,offset=698724,lag=1
(...)

infoではメモリの使用量やステータスの確認ができる。

slave側は次の様に表示される。

node2$ redis-cli -p 6379 info replication
# Replication
role:slave
master_host:192.168.33.10
master_port:6379
master_link_status:up
(...)

Sentinelの確認

$ redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.33.10:6379,slaves=2,sentinels=3

最後の行でstatusやMasterのアドレスやスレーブの台数、sentinelの台数が確認できる。

Master名を指定してMasterを問い合わせる場合は次のコマンドを実効する。

$ redis-cli -p 26379 sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "192.168.33.10"
5) "port"
6) "6379"
(...)

データの操作

アプリケーションからは複数台のsentinelに対してRedisのmasterを問い合わせして、Sentinelの応答に記載されているMasterに接続するするような流れになる。Sentinelに対してRedisのデータを変更する操作をしてもエラーしか出ない。また、SlaveはRead Onlyなのでデータは書き込めない。

$ redis-cli -p 6379
127.0.0.1:6379> set "hoge" "fuga"
OK
127.0.0.1:6379> get "hoge"
"fuga"
127.0.0.1:6379> exit
$ redis-cli -p 26379
127.0.0.1:26379> get "hoge"
(error) ERR unknown command 'get'
127.0.0.1:26379> set "hoge" "fuga"
(error) ERR unknown command 'set'
127.0.0.1:26379>

小ネタ

Redisはたくさんコマンドがあるので覚えるのが大変だが、redis-cliでは1文字も入力していない状況でTABを押すとコマンドが表示され、コマンドのHINTも表示される。困ったらTABを連打すると良い。

設定ファイル

Sentinelは自身の設定ファイルを自分自身で動的に書き換えるので注意が必要。
Redisもslaveofあたりを書き換えることがある。

sentinelが追加した設定は次の通り。

# node1のSentinel設定
node1$ cat /etc/redis/26379.conf
(...)
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 192.168.33.12 6379
sentinel known-slave mymaster 192.168.33.11 6379
sentinel known-sentinel mymaster 192.168.33.12 26379 0f3f866b99e4d3f73f05ced9fba7678dd9906e49
sentinel known-sentinel mymaster 192.168.33.11 26379 02509d3ec85497490fbbc92047425602f1290150
sentinel current-epoch 0

# node2のSentinel設定
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 192.168.33.11 6379
sentinel known-slave mymaster 192.168.33.12 6379
sentinel known-sentinel mymaster 192.168.33.10 26379 4c70b2e17998704a645c81bc3a3c4372aecc4511
sentinel known-sentinel mymaster 192.168.33.12 26379 0f3f866b99e4d3f73f05ced9fba7678dd9906e49
sentinel current-epoch 0

# node3のSentinel設定
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 192.168.33.12 6379
sentinel known-slave mymaster 192.168.33.11 6379
sentinel known-sentinel mymaster 192.168.33.10 26379 4c70b2e17998704a645c81bc3a3c4372aecc4511
sentinel known-sentinel mymaster 192.168.33.11 26379 02509d3ec85497490fbbc92047425602f1290150
sentinel current-epoch 0

フェイルオーバーの確認

デフォルトでは30秒間スレーブとの通信ができないとSlave側がMasterに障害が発生したと判断してフェイルオーバーする。

スレーブ側でmasterとの通信をmonitorで監視しておく。正しく通信ができている場合は次の様に出力される。

$ redis-cli -p 6379 monitor
OK
1475345227.895510 [0 192.168.33.11:50096] "PUBLISH" "__sentinel__:hello" "192.168.33.11,26379,02509d3ec85497490fbbc92047425602f1290150,0,mymaster,192.168.33.10,6379,0"
1475345227.915043 [0 192.168.33.12:49664] "PUBLISH" "__sentinel__:hello" "192.168.33.12,26379,0f3f866b99e4d3f73f05ced9fba7678dd9906e49,0,mymaster,192.168.33.10,6379,0"

masterで次のコマンドを実行してフェイルオーバーさせる。

node1$ redis-cli -p 6379 DEBUG sleep 3000

monitorの出力にに192.168.33.10との通信が表示されなくなりmasterが切り替わる。

$ redis-cli -p 26379 sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "192.168.33.11"
5) "port"
6) "6379"
(...)

切り替わったmaster(node2)のredisの設定ファイルからslaveofの項目が削除され、slaveのslaveofが切り替わったmasterに書き換えられた。

sentinelの設定ファイルのmasterのアドレスも新しいmasterのアドレスに書き換えられた。

node1を回復させると、slaveとして復帰する。redisの設定ファイルの末尾にslaveof 192.168.33.11 6379が追加されているので何かしら復帰させる仕組みがあると思われる。

$ redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.33.11:6379,slaves=2,sentinels=3

sentinelを停止してみる

node1のsentinelを停止させたが、sentinelを停止させても出力される状態は変わらなかった。

$ redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.33.11:6379,slaves=2,sentinels=3

sentinelの状態を現状の状態に合わせるためにはリセットする必要がありそう。

$ redis-cli -p 26379 sentinel reset mymaster
(integer) 1
$ redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.33.11:6379,slaves=2,sentinels=2

細かいところも引き続き調べる必要があるが今回はここまで。

終わり。

参考

  1. http://redis.io/topics/cluster-tutorial
  2. http://redis.io/topics/sentinel
  3. http://qiita.com/wellflat/items/8935016fdee25d4866d9