Redis Cluster でマスタ・スレーブのクラスタ構成を構築してみた

Redis 3.0 から正式に追加された機能である Redis Cluster を使って、同一サーバ内で、マスタが 3 インスタンス、スレーブが 3 インスタンスクラスタ構成を構築してみました。

図にするとこちらのような構成です。

f:id:enomotodev:20170602213336p:plain

作業環境

Redis をインストールする

今回は全て root で作業を行ったので、root に変更します。

$ sudo su -

あとで redis-trib.rb を使って、クラスタ構成とレプリケーションを設定するので、Ruby などのパッケージをインストールしておきます

# yum install ruby
# ruby --version
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
# gem install redis

次に、Redis をソースからインストールします。

# wget http://download.redis.io/releases/redis-3.2.9.tar.gz
# tar xzf redis-3.2.9.tar.gz
# cd redis-3.2.9
# make
# make install

これで Redis のインストールは完了したのでバージョンを確認します。

# redis-server --version
Redis server v=3.2.9 sha=00000000:0 malloc=jemalloc-4.0.3 bits=64 build=ccbe915be5386293

マスタ・スレーブのクラスタ構成を構築する

今回は下の図のように1つのサーバでポートを分けて Redis を起動させてクラスタ構成を構築していきたいと思います。

f:id:enomotodev:20170602214131p:plain

まずは、それぞれのポート用の conf ファイルを作成し、それを元に Redis を起動させます。

# mkdir -p /opt/redis-cluster/700{0..5}
# cat <<EOS > redis.conf
port 7000
cluster-enabled yes
cluster-config-file /opt/redis-cluster/7000/nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize yes
EOS
# for i in {0..5}; do cp -av redis.conf "/opt/redis-cluster/700$i/"; sed -i -e "s/7000/700$i/g" "/opt/redis-cluster/700$i/redis.conf"; done
# for i in {0..5}; do redis-server /opt/redis-cluster/700$i/redis.conf; done

起動できているか確認してみます。

# ps aux | grep redis | grep -v grep
root      1617  0.0  0.7 141016  7580 ?        Ssl  07:53   0:00 redis-server *:7000 [cluster]
root      1621  0.0  0.7 136920  7544 ?        Ssl  07:53   0:00 redis-server *:7001 [cluster]
root      1623  0.0  0.7 136920  7548 ?        Ssl  07:53   0:00 redis-server *:7002 [cluster]
root      1625  0.0  0.7 136920  7544 ?        Ssl  07:53   0:00 redis-server *:7003 [cluster]
root      1629  0.0  0.7 136920  7544 ?        Ssl  07:53   0:00 redis-server *:7004 [cluster]
root      1633  0.0  0.7 136920  7548 ?        Ssl  07:53   0:00 redis-server *:7005 [cluster]

この状態ではそれぞれが単独のマスタとなっているので、これをマスタ・スレーブのクラスタ構成にします。

クラスタ構成にするにはそれぞれの Redis を起動した状態で redis-trib.rb create コマンドで簡単に設定できます。

--replicas 1 オプションでそれぞれ1つのマスタに1つのスレーブを設定するという意味になります。

# ./src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.01:7004 127.0.0.1:7005

これでクラスタ構成を構築できたので確認してみます。

# redis-cli -p 7000 cluster nodes
7619bc693126ebfc684f6373af297b124670a018 127.0.0.1:7001 master - 0 1496390202022 2 connected 10923-16383
9bec110278fb159540c6d8aa0f215a81bb0d6e3b 127.0.0.1:7004 master - 0 1496390204038 5 connected 5461-10922
046b85341f98820141a89704b966fc0ed3a79304 127.0.0.1:7003 slave 9bec110278fb159540c6d8aa0f215a81bb0d6e3b 0 1496390202022 5 connected
6fb9cccaab638b2bcaa69598dd3acdd36b792588 127.0.0.1:7002 slave cc994cf3f71b95e36046f8eb65db060133bea306 0 1496390202527 3 connected
1b20ef4dadb0aa7f1fc693078709d0cbc3047d64 127.0.0.1:7005 slave 7619bc693126ebfc684f6373af297b124670a018 0 1496390203030 6 connected
cc994cf3f71b95e36046f8eb65db060133bea306 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460

次に、下図のように、7004 番ポートの Redis (マスタ)をわざと停止させるとどうなるか確認してみたいと思います。

f:id:enomotodev:20170602214135p:plain

# ps aux | grep redis | grep -v grep
root      1617  0.0  0.9 141016  9800 ?        Ssl  07:53   0:00 redis-server *:7000 [cluster]
root      1621  0.0  0.9 138968  9772 ?        Ssl  07:53   0:00 redis-server *:7001 [cluster]
root      1623  0.0  0.7 136920  7740 ?        Ssl  07:53   0:00 redis-server *:7002 [cluster]
root      1625  0.0  0.7 136920  7736 ?        Ssl  07:53   0:00 redis-server *:7003 [cluster]
root      1629  0.0  0.9 138968  9772 ?        Ssl  07:53   0:00 redis-server *:7004 [cluster]
root      1633  0.0  0.7 136920  7740 ?        Ssl  07:53   0:00 redis-server *:7005 [cluster]

7004 番ポートの Redis の PID を確認し kill します。

# kill -9 1629

もう一度、構成を確認してみます。

# redis-cli -p 7000 cluster nodes
7619bc693126ebfc684f6373af297b124670a018 127.0.0.1:7001 master - 0 1496390360732 2 connected 10923-16383
9bec110278fb159540c6d8aa0f215a81bb0d6e3b 127.0.0.1:7004 master,fail - 1496390301201 1496390300798 5 disconnected
046b85341f98820141a89704b966fc0ed3a79304 127.0.0.1:7003 master - 0 1496390362242 7 connected 5461-10922
6fb9cccaab638b2bcaa69598dd3acdd36b792588 127.0.0.1:7002 slave cc994cf3f71b95e36046f8eb65db060133bea306 0 1496390362744 3 connected
1b20ef4dadb0aa7f1fc693078709d0cbc3047d64 127.0.0.1:7005 slave 7619bc693126ebfc684f6373af297b124670a018 0 1496390361738 6 connected
cc994cf3f71b95e36046f8eb65db060133bea306 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460

確認すると、7004 番ポートの Redis から 7003 番ポートの Redis がマスタに昇格したのが確認できると思います。

f:id:enomotodev:20170602214138p:plain

まとめ

今回は Redis Cluster を使って、Redis のマスタ・スレーブのクラスタ構成を構築してみました。

構築するだけであれば redis-trib.rb を使うと、簡単に構築できるので、気軽にシステムの可用性向上につなげることができそうです。

ただ、Redis Cluster だと集合演算など、一部制約を受ける部分もあるようなので、その辺もこれから調べていきたいと思います。