概要
前回はマスターのみでRedis Clusterを構築しました。
今回は冗長構成で構築し、可用性を確認します。
環境
- Redis 5.0.7
Replicationを含めた冗長構成
各シャード1台ずつReplicationを用意して冗長構成にしてみます。
システム図
イメージはこちら
設定
docker-compose.yaml
6台起動させます。
version: '3' services: node_1: &base image: redis:alpine volumes: - $PWD/redis.conf:/usr/local/etc/redis/redis.conf command: redis-server /usr/local/etc/redis/redis.conf networks: - redis_net node_2: <<: *base node_3: <<: *base node_4: <<: *base node_5: <<: *base node_6: <<: *base networks: redis_net: driver: bridge ipam: driver: default config: - subnet: 172.30.0.0/24
cluster構築
起動できたらその内1台に入ります。
$ docker exec -it cluster_node_1_1 /bin/ash
そしてcluster構築コマンドを実行します。
今回は--cluster-replicas
オプションを付けます。
data# redis-cli --cluster create \ 172.30.0.2:6379 172.30.0.3:6379 \ 172.30.0.4:6379 172.30.0.5:6379 \ 172.30.0.6:6379 172.30.0.7:6379 \ --cluster-replicas 1
--cluster-replicas 1
とするとマスター毎に1つのreplicaを追加します。
また前回同様自動でhash slotsを配分してくれます。
>>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 172.30.0.6:6379 to 172.30.0.2:6379 Adding replica 172.30.0.7:6379 to 172.30.0.3:6379 Adding replica 172.30.0.5:6379 to 172.30.0.4:6379 M: 0c4f3f7417cd2adb374f4ef9999171c909bd31f6 172.30.0.2:6379 slots:[0-5460] (5461 slots) master M: e8fb2156906daefe3dc09adac242cb53bee14d54 172.30.0.3:6379 slots:[5461-10922] (5462 slots) master M: 69815efc30606972f6fb02d931f135e86091065a 172.30.0.4:6379 slots:[10923-16383] (5461 slots) master S: 1e3727c7adfef0b11f7f85dbe60db16fabb5b45c 172.30.0.5:6379 replicates 69815efc30606972f6fb02d931f135e86091065a S: 35d8403388b5d1d161eb585875070c3a3d7528d6 172.30.0.6:6379 replicates 0c4f3f7417cd2adb374f4ef9999171c909bd31f6 S: 5454de425f533ab1693be1f700e0798f551dec30 172.30.0.7:6379 replicates e8fb2156906daefe3dc09adac242cb53bee14d54 Can I set the above configuration? (type 'yes' to accept):
上記設定で問題なければyes
を入力。
>>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join .. >>> Performing Cluster Check (using node 172.30.0.2:6379) M: 0c4f3f7417cd2adb374f4ef9999171c909bd31f6 172.30.0.2:6379 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: 5454de425f533ab1693be1f700e0798f551dec30 172.30.0.7:6379 slots: (0 slots) slave replicates e8fb2156906daefe3dc09adac242cb53bee14d54 S: 35d8403388b5d1d161eb585875070c3a3d7528d6 172.30.0.6:6379 slots: (0 slots) slave replicates 0c4f3f7417cd2adb374f4ef9999171c909bd31f6 S: 1e3727c7adfef0b11f7f85dbe60db16fabb5b45c 172.30.0.5:6379 slots: (0 slots) slave replicates 69815efc30606972f6fb02d931f135e86091065a M: 69815efc30606972f6fb02d931f135e86091065a 172.30.0.4:6379 slots:[10923-16383] (5461 slots) master 1 additional replica(s) M: e8fb2156906daefe3dc09adac242cb53bee14d54 172.30.0.3:6379 slots:[5461-10922] (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
作成できました。
/data # redis-cli --cluster info 172.30.0.2:6379 172.30.0.2:6379 (0c4f3f74...) -> 0 keys | 5461 slots | 1 slaves. 172.30.0.4:6379 (69815efc...) -> 0 keys | 5461 slots | 1 slaves. 172.30.0.3:6379 (e8fb2156...) -> 0 keys | 5462 slots | 1 slaves. [OK] 0 keys in 3 masters.
前回と違って1 slaves
になっていますね。
Failover
replicaがいるため、仮にmasterが死んだとしても
Redis Clusterでは以下のようにreplicaがmasterへ昇格します。
この挙動を検証してみます。
検証
検証のため適当にデータを入れておきます。
/data # redis-cli -c 127.0.0.1:6379> set 1 1 -> Redirected to slot [9842] located at 172.30.0.3:6379 OK 172.30.0.3:6379> set 2 2 OK 172.30.0.3:6379> set 3 3 -> Redirected to slot [1584] located at 172.30.0.2:6379 OK 172.30.0.2:6379> set 4 4 -> Redirected to slot [14039] located at 172.30.0.4:6379 OK 172.30.0.4:6379> set 5 5 -> Redirected to slot [9974] located at 172.30.0.3:6379 OK 172.30.0.3:6379> set 6 6 OK 172.30.0.3:6379> /data # redis-cli --cluster info 172.30.0.2:6379 172.30.0.2:6379 (0c4f3f74...) -> 1 keys | 5461 slots | 1 slaves. 172.30.0.4:6379 (69815efc...) -> 1 keys | 5461 slots | 1 slaves. 172.30.0.3:6379 (e8fb2156...) -> 4 keys | 5462 slots | 1 slaves. [OK] 6 keys in 3 masters.
172.30.0.2
のコンテナをstopさせます。
$ docker stop cluster_node_2_1
するとredisのログでは以下のように昇格のための選出が行われます。今回node_6_1(172.30.0.6)
が勝ったようです。
node_6_1 | 1:S 31 Mar 2020 18:32:42.850 # Starting a failover election for epoch 8. node_4_1 | 1:M 31 Mar 2020 18:32:42.854 # Failover auth granted to 35d8403388b5d1d161eb585875070c3a3d7528d6 for epoch 8 node_5_1 | 1:M 31 Mar 2020 18:32:42.854 # Failover auth granted to 35d8403388b5d1d161eb585875070c3a3d7528d6 for epoch 8 node_6_1 | 1:S 31 Mar 2020 18:32:42.856 # Failover election won: I'm the new master.
クラスタの状態を確認します。
# redis-cli --cluster info 172.30.0.3:6379 Could not connect to Redis at 172.30.0.2:6379: Host is unreachable 172.30.0.3:6379 (e8fb2156...) -> 4 keys | 5462 slots | 1 slaves. 172.30.0.4:6379 (69815efc...) -> 1 keys | 5461 slots | 1 slaves. 172.30.0.6:6379 (35d84033...) -> 1 keys | 5461 slots | 0 slaves. [OK] 6 keys in 3 masters.
172.30.0.2
が死んだので、replicaだった172.30.0.6
がmasterに昇格しています。
データ操作
replicaだった172.30.0.6
にも書き込みができることを確認できます。
172.30.0.3:6379> set 3 3 -> Redirected to slot [1584] located at 172.30.0.6:6379 OK
落としたコンテナを起動してみる
172.30.0.2
を起動してみます。
/data # redis-cli --cluster info 172.30.0.3:6379 172.30.0.3:6379 (e8fb2156...) -> 4 keys | 5462 slots | 1 slaves. 172.30.0.4:6379 (69815efc...) -> 1 keys | 5461 slots | 1 slaves. 172.30.0.6:6379 (35d84033...) -> 1 keys | 5461 slots | 1 slaves. [OK] 6 keys in 3 masters.
すると今度は172.30.0.2
が172.30.0.6
のreplicaに代わりました。
自動でfail backはしないようです。
許容できるダウン台数
failoverの図を見て分かるように、シャードにノードが残っているかが重要です。
まだOK
各シャード内でそれぞれ最低1台残っていれば稼働できます。
アウト
しかしシャード内の全ノードが死んだ場合はRedis Clusterはサービス不能になります。
Shard 0
のノードを全て落としてみると
node_4_1 | 1:M 01 Apr 2020 01:04:39.599 # Cluster state changed: fail node_3_1 | 1:S 01 Apr 2020 01:04:39.599 * Marking node 35d8403388b5d1d161eb585875070c3a3d7528d6 as failing (quorum reached). node_3_1 | 1:S 01 Apr 2020 01:04:39.599 # Cluster state changed: fail node_1_1 | 1:S 01 Apr 2020 01:04:39.600 * Marking node 35d8403388b5d1d161eb585875070c3a3d7528d6 as failing (quorum reached). node_1_1 | 1:S 01 Apr 2020 01:04:39.600 # Cluster state changed: fail node_5_1 | 1:M 01 Apr 2020 01:04:39.600 * Marking node 35d8403388b5d1d161eb585875070c3a3d7528d6 as failing (quorum reached). node_5_1 | 1:M 01 Apr 2020 01:04:39.600 # Cluster state changed: fail
redisログ上では各ノードのCluster stateがfail
に変わります。
そうなるとcluster infoは取れますが
/data # redis-cli --cluster info 172.30.0.3:6379 Could not connect to Redis at 172.30.0.2:6379: Host is unreachable Could not connect to Redis at 172.30.0.6:6379: Host is unreachable 172.30.0.3:6379 (e8fb2156...) -> 4 keys | 5462 slots | 1 slaves. 172.30.0.4:6379 (69815efc...) -> 1 keys | 5461 slots | 1 slaves. [OK] 5 keys in 2 masters.
データ操作しようとしてもできません。
/data # redis-cli -c 127.0.0.1:6379> get 1 (error) CLUSTERDOWN The cluster is down 127.0.0.1:6379> get 2 (error) CLUSTERDOWN The cluster is down 127.0.0.1:6379> get 3 (error) CLUSTERDOWN The cluster is down
Cluster down後にmasterが復帰した場合
上記の検証でダウンさせたShard 0
のノードを復帰させてみます。
$ docker start cluster_node_6_1
cluster_node_6_1
復帰したノードはそのままmasterとなります。
/data # redis-cli --cluster info 172.30.0.3:6379 172.30.0.3:6379 (e8fb2156...) -> 4 keys | 5462 slots | 1 slaves. 172.30.0.4:6379 (69815efc...) -> 1 keys | 5461 slots | 1 slaves. 172.30.0.2:6379 (35d84033...) -> 1 keys | 5461 slots | 0 slaves. [OK] 6 keys in 3 masters.
redisログを見ると各ノードのCluster stateはok
に変わり、
node_4_1 | 1:M 01 Apr 2020 01:11:06.037 # Cluster state changed: ok node_1_1 | 1:S 01 Apr 2020 01:11:06.037 * Clear FAIL state for node 35d8403388b5d1d161eb585875070c3a3d7528d6: is reachable again and nobody is serving its slots after some time. node_1_1 | 1:S 01 Apr 2020 01:11:06.037 # Cluster state changed: ok node_3_1 | 1:S 01 Apr 2020 01:11:06.037 * Clear FAIL state for node 35d8403388b5d1d161eb585875070c3a3d7528d6: is reachable again and nobody is serving its slots after some time. node_3_1 | 1:S 01 Apr 2020 01:11:06.037 # Cluster state changed: ok node_5_1 | 1:M 01 Apr 2020 01:11:06.037 * Clear FAIL state for node 35d8403388b5d1d161eb585875070c3a3d7528d6: is reachable again and nobody is serving its slots after some time. node_5_1 | 1:M 01 Apr 2020 01:11:06.037 # Cluster state changed: ok node_6_1 | 1:M 01 Apr 2020 01:11:07.993 # Cluster state changed: ok
データ操作も可能になります。
/data # redis-cli -c 127.0.0.1:6379> get 1 -> Redirected to slot [9842] located at 172.30.0.3:6379 "1"
まとめ
Redis Clusterを冗長構成で構築し、簡単なfailover検証をしてみました。