2015年8月13日木曜日

Redis Cluster にスレーブノードを追加する方法

概要

前回 までに Redis Cluster を構築し SLOTS についても触れました
今回はノードの追加に関して触れていこうと思います
特に今回は Redis Cluster + Master -Slave 構成を取る方法を例に紹介します

環境

  • Mac OS X 10.10.4
  • Redis 3.0.2

環境構築

環境構築に関しては前回の記事を参考にしてください
Redis Cluster 内に Master が3台ある状態でスタートしたいと思います

追加するノードを準備する

Redis 3.0 以上が動作するノードが準備できればOKです
今回は同一マシン上にノードを追加しますが、もちろんマシンを1台追加して、そこで Redis を動作させてもOKです

まず追加するノードを管理するディレクトリを作成しましょう

cd work/redis-cluster
mkdir 7003
cp /usr/local/etc/redis.conf.default 7003/redis.conf
vim 7003/redis.conf

以下の部分を書き換えます

  • port 7003
  • appendonly yes
  • cluster-enabled yes
  • cluster-config-file nodes-7003.conf
  • cluster-node-timeout 5000

設定ファイルが作成できたら redis を起動しましょう

redis-server work/redis-cluster/7003/redis.conf

もちろんですが、まだ起動しただけでは Redis Cluster には追加されていません
CLUSTER NODESコマンドなどを実行して確認してみると、まだ存在していないのがわかると思います
また、1台なので cluster status も fail になっている思います

作成したノードを追加する

現状は Master ノードが 3 台いる状態で本当であれば、あと 2 台ノードを追加して各 Master ノードに対して Slave ノードを追加したいところですが、今回はとりあえず 1 台の Slave ノードを追加します

追加にはredis-trib.rbを使います
実行するコマンドは以下の通りです

./redis-3.0.3/src/redis-trib.rb add-node --slave 127.0.0.1:7003 127.0.0.1:7000

コマンドの説明です
まず、今回は Slave ノードとして追加したいため add-node コマンドのオプションとして--slaveオプションを使います
–slave オプションの直後に Slave として追加したいノードを指定します
なので今回は127.0.0.1:7003が追加したいノードになります
次の引数ですが、これは Master として動作している既存のノードを指定します
127.0.0.1:7000はすでに Master ノードとして Redis Cluster 内で動作しています
この Master ノードに対する Slave ノードとして Redis Cluster に追加するコマンドになります

では、実際に実行してみましょう

>>> Adding node 127.0.0.1:7003 to cluster 127.0.0.1:7000
Connecting to node 127.0.0.1:7000: OK
Connecting to node 127.0.0.1:7002: OK
Connecting to node 127.0.0.1:7001: OK
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: dc1e153c61deb8e932327bbdd81edac4c9ce8ba6 127.0.0.1:7000
   slots:0-5460,5741 (5462 slots) master
   0 additional replica(s)
M: cb7a9481f21521dda296de4fefbf11937d9de153 127.0.0.1:7002
   slots:10923-16383 (5461 slots) master
   0 additional replica(s)
M: cf0bbf4043129b3022eff0dc385530d7c6d9f527 127.0.0.1:7001
   slots:5461-5740,5742-10922 (5461 slots) master
   0 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 127.0.0.1:7000
Connecting to node 127.0.0.1:7003: OK
>>> Send CLUSTER MEET to node 127.0.0.1:7003 to make it join the cluster.
Waiting for the cluster to join....
>>> Configure node as replica of 127.0.0.1:7000.
[OK] New node added correctly.

上記は正常に追加された場合のログになります
追加されたCLUSTER NODESで確認してみましょう

127.0.0.1:7003> cluster nodes
cf0bbf4043129b3022eff0dc385530d7c6d9f527 127.0.0.1:7001 master - 0 1439368898457 2 connected 5461-5740 5742-10922
dc1e153c61deb8e932327bbdd81edac4c9ce8ba6 127.0.0.1:7000 master - 0 1439368899488 1 connected 0-5460 5741
e8915b149eab015c0e23ec9818e6e6251115e6b0 127.0.0.1:7003 myself,slave dc1e153c61deb8e932327bbdd81edac4c9ce8ba6 0 0 0 connected
cb7a9481f21521dda296de4fefbf11937d9de153 127.0.0.1:7002 master - 0 1439368897435 3 connected 10923-16383

7003 のノードが 7000 の slave として登録されていることがわかると思います
myself, slave の後に記載されているランダムな文字列が node-id
でここに記載されている node-id に対する slave ノードだということを表しています

Failover を試してみる

試しに 7000 のノードをダウンさせてちゃんと 7003 が master に昇格するか確認してみましょう

7000 のノードをダウンさせると 7003 のログに以下のようなログが出ると思います

1443:S 12 Aug 17:46:19.933 * MASTER <-> SLAVE sync started
1443:S 12 Aug 17:46:19.934 # Error condition on socket for SYNC: Connection refused

ある程度の時間 Master ノードとの通信ができないと Failover が発生します
おそらく cluster-node-timeout で指定した時間 Master ノードから応答がないと Failover させる感じだと思います
Failover が発生すると以下のようなログが流れます

1443:S 12 Aug 17:46:20.448 # Starting a failover election for epoch 4.
1443:S 12 Aug 17:46:20.457 # Failover election won: I'm the new master.
1443:S 12 Aug 17:46:20.457 # configEpoch set to 4 after successful failover
1443:M 12 Aug 17:46:20.457 * Discarding previously cached master state.
1443:M 12 Aug 17:46:20.457 # Cluster state changed: ok

Redis Cluster のステータス自体も ok になっていることがわかると思います
この状態でCLUSTER NODESを見てみると
ダウンした 7000 ノードが fail になっていることがわかります

再度 7000 ノードの redis をスタートしてみましょう
すると、7000 番のノードが自動的に 7003 番の Slave ノードとして登録されることが確認できると思います

127.0.0.1:7003> cluster nodes
cf0bbf4043129b3022eff0dc385530d7c6d9f527 127.0.0.1:7001 master - 0 1439369412563 2 connected 5461-5740 5742-10922
dc1e153c61deb8e932327bbdd81edac4c9ce8ba6 127.0.0.1:7000 slave e8915b149eab015c0e23ec9818e6e6251115e6b0 0 1439369408140 4 connected
e8915b149eab015c0e23ec9818e6e6251115e6b0 127.0.0.1:7003 myself,master - 0 0 4 connected 0-5460 5741
cb7a9481f21521dda296de4fefbf11937d9de153 127.0.0.1:7002 master - 0 1439369411538 3 connected 10923-16383

一度死んだノードを再度起動するだけで自動的に Slave として登録してくれるのは便利だと思います

トラブルシュート

特に問題なければ簡単に追加することができます
問題が発生するケースとしては

  • Redis Cluster に追加したいノード上にすでにデータが入っている
  • 追加したいノードが Cluster モードで起動していない
  • 追加したい Redis Cluster が壊れている

あたりかなと思います
1つ目は一旦データをFLUSHALLしてから Redis Cluster 用の設定ファイル ( Mac であれば /usr/local/var/db/redis/nodes-7003.conf とか) を削除して、再度 redis を起動しましょう
2つ目は設定ファイル redis.conf を確認してみましょう
3つ目はそもそもやばい状態です
対応するとしたらredis-trib.rbfixというコマンドがあるのでこれを使うといいかもしれません
それでもダメだとしたら appendonly.aof を削除したり、設定ファイルを削除したりと本格的に Redis Cluster の再構築をしなければいけないことになるのかもしれません

最後に

Redis Cluster は最低 3 個のノードが必要になるので Master - Slave 構成をとろうとするとそれだけで 6 個のノードが必要になります
サービスとして運用するのであれば Master - Slave 構成は必須だと思いますが、Master ノードを追加するたびに Slave ノードも必要になるのでインフラコストは大きくなりそうな気がしました
ノードは1台のマシンで複数のノードを持つことができるのでそれでもいいのかなと思いますが、それだと DR 的にはダメだと思います

0 件のコメント:

コメントを投稿