Redis Sentinelを動かしてみた
以前、Redis Sentinelを試すというエントリーを書きましたが
もう少し入り込んで検証してみた。
殴り書きの域を出ていないので適時アップデートしていきたい。
検証環境
- DATE: 2013/01/25
- CentOS 6.3
- Redis 2.6.9(remi)
ドキュメント
http://redis.io/topics/sentinel
こちらを参考に行います。
Sentinelの設定、および起動方法
$ /usr/local/bin/redis-server /etc/sentinel.conf --sentinel [28498] 25 Jan 01:28:24.447 * Max number of open files set to 10032 _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 2.6.9 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in sentinel mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 26379 | `-._ `._ / _.-' | PID: 28498 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' [28498] 25 Jan 01:28:24.451 * +slave slave 192.168.2.102:6379 192.168.2.102 6379 @ mymaster 192.168.2.101 6379 [28498] 25 Jan 01:28:25.358 * +sentinel sentinel 192.168.2.101:26379 192.168.2.101 26379 @ mymaster 192.168.2.101 6379
こんな感じで起動します。
設定ファイル
参考: http://download.redis.io/redis-stable/sentinel.conf
sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 60000 sentinel failover-timeout mymaster 900000 sentinel can-failover mymaster yes sentinel parallel-syncs mymaster 1
オフィシャルの設定ファイルを参考に。
設定の意味
sentinel monitor <master-name> <ip> <redis-port> <quorum>
この<quorum>
はRedis-Sentinelの数を指します。
Redis-Sentinelは、他のRedis-Sentinelが接続してきた場合に
相互に理解する働きがあります。
この機能によってSplit-brain-syndromeを防ぐことが可能です。
Redisのレプリケーションが正常に行えている状態
Redisのレプリケーションの回線に障害が発生した場合
上記のように、レプリケーションの経路に異常が発生した場合
Split-brain-syndromeが起こり
レプリケーション情報は保てなくなり、お互いがMasterと認識してしまう問題があります。
上記のような状況を避ける為に<quorum>
の設定があります。
このquorumの値は、監視しているRedis-Sentinelの数を表しています。
上記のようにレプリケーションの経路に異常があった場合であっても
<quorum>
で設定した数のSentinelが異常を検知して初めてフェイルオーバーが始まります。
SentinelはSentinel同士で理解し合う機能が搭載されているんですね。
人間にもそんな機能があったら争いとかなくなりますかね。
Redis-Sentinelの連絡が行えなくなり、Split-brain-syndromeは起こらない
ということで、<quorum>
を2台以上設定することで、
予期しないフェイルオーバーを予防することが可能です。
sentinel down-after-milliseconds mymaster 60000
SentinelがDOWNを検知してからのフェイルオーバーを始めるまでのアイドル時間。
DOWNと認める条件はドキュメントを参照。
ODOWNとSDOWNについてももう少し書きたい。
検証時では 5000milliseconds ぐらいが問題なく動作した。
スペックや環境によってはもっとストイックな設定が可能。
なお、実際にMasterが切り替わるまで 5~15秒 の間でランダムな待ち時間が発生する。
Sentinel Rule #14: A Sentinel detects a failover as an Observer (that is, the Sentinel just follows the failover generating the appropriate events in the log file and Pub/Sub interface, but without actively reconfiguring instances) if the following conditions are true at the same time: * There is no failover already in progress. * A slave instance of the monitored master turned into a master. However the failover will NOT be sensed as started if the slave instance turns into a master and at the same time the runid has changed from the previous one. This means the instance turned into a master because of a restart, and is not a valid condition to consider it a slave election.
Sentinel Rule #15: A Sentinel starting a failover as leader does not immediately starts it. It enters a state called wait-start, that lasts a random amount of time between 5 seconds and 15 seconds. During this time Sentinel Rule #14 still applies: if a valid slave promotion is detected the failover as leader is aborted and the failover as observer is detected.
詳細はドキュメントの Sentinel Rule #14,#15 を参照。
なので、フェイルオーバーが開始されるタイミングは
down-after-milliseconds + 5~15秒 の時間になります。
sentinel failover-timeout mymaster 900000
フェイルオーバーを開始してから、レスポンスが返ってくるまでの
待ち時間。詳細はやはりドキュメントを読んでほしい。
検証時に "10 milliseconds" などストイックな設定を行なってみたが タイムアウトに引っかかり、レプリケーションが開始することはなかった... こちらもやはり "5000 milliseconds" ぐらいが安全であった
sentinel can-failover mymaster yes
mymasterのダウン時に、フェイルオーバーを実行するか否かの設定。
sentinel parallel-syncs mymaster 1
フェイルオーバーが実行された後、新しいマスターを
使用するように並列で再構成することができるスレーブの数の指定。
Slaveサーバが多く、この設定数が低いほど、
フェイルオーバーの処理に時間がかかるとのこと。
(未検証)
おまけ:レプリケーションの構築手順
Slave(192.168.2.102)
$ echo "slaveof 192.168.2.101 6379" | redis-cli -h 192.168.2.102 OK $ $ redis-cli -h 192.168.2.102 info | grep -E 'mas|sla' role:slave master_host:192.168.2.101 master_port:6379 master_link_status:up master_last_io_seconds_ago:5 master_sync_in_progress:0 slave_priority:100 slave_read_only:1 connected_slaves:0 $
Master(192.168.2.101)
$ redis-cli -h 192.168.2.101 info | grep -E 'mas|sla' role:master connected_slaves:1 slave0:192.168.2.102,6379,online $
レプリケーションの情報
master_host:192.168.2.101
MasterのIPアドレス情報master_port:6379
MasterのPort番号情報master_link_status:up
Masterの状態の情報master_last_io_seconds_ago
Slaveは10秒間隔でMasterへPINGを送信している。
その"正常な"データを受信してからの経過時間の情報
monitor
コマンドで確認することができる。
$ redis-cli -h 192.168.2.102 monitor OK 1359037270.075903 [0 192.168.2.101:6379] "PING" 1359037280.274001 [0 192.168.2.101:6379] "PING" 1359037290.464774 [0 192.168.2.101:6379] "PING"
master_sync_in_progress
Masterからデータを受信状況(SYNC)の情報
SYNC中であれば 1 のフラグが立ち、状況の詳細が表示される。
詳細はこちら : INFO / Redis
Masterが落ちていた場合の状態
master_link_status:down master_last_io_seconds_ago:-1 master_sync_in_progress:0 master_link_down_since_seconds:N
PINGの間隔が10秒間隔なので、疎通チェックも10秒間隔かと思うが
そうではない(もう少し調べる)。
おまけのおまけ
SlaveのSlaveも設定可能
101.slave(Master) <= 102.6379(Slave) <= 102.6380(Slave)
$ redis-cli -h 192.168.2.102 info | grep -E 'mas|sla' role:slave master_host:192.168.2.101 master_port:6379 master_link_status:up master_last_io_seconds_ago:7 master_sync_in_progress:0 slave_priority:100 slave_read_only:1 connected_slaves:1 slave0:192.168.2.102,6380,online $
また、MasterとSlaveの接続が切れた場合も
Slave <=> Slaveの同期は停止する。(検証済み)
master_last_io_seconds_ago が Sentinel立ち上げる事に間隔が短かくなる
3台上げたらほとんど1秒間隔になった。
ということで
Sentinel、よく考えられているなという印象です。
以上、この情報が何かのお役に立てれば幸いです。
This HOWTO is a work in progress, more information will be added in the near future.
https://github.com/antirez/redis-doc/blob/master/topics/sentinel.md
ということで、活発的に開発が行われているので
適時チェックするのが良さそうですね。