これは、なにをしたくて書いたもの?
- Redis 5.0がリリースされ、クラスタを構成するコマンド が新しくなったらしい
- 久しぶりに、Redis Clusterを構成して遊んでみよう
という、単にRedis 5.0での手順でRedis Clusterを構成してみようというエントリです。
なお、Redis 3.0の頃にRedis Clusterを構成して遊んだこともあるので、こちらを見つつどう変わっていったかを確認して
いきたいと思います。
Ubuntu LinuxでRedis ClusterのDockerイメージを作って遊ぶ - CLOVER🍀
Redis 5.0の更新内容は、こちらにまとまっているので参考にさせていただきました。
Redis Clusterってなに?
前回のエントリでも書いているのですが、おさらい的に。
- 複数のRedisノードを使って構成するクラスタで、データは自動的にシャーディングして保持される
- 一部のサーバーで障害があっても、処理を継続可能
- スレーブ(レプリカ)を持てる
ただ、大規模な障害(多数のマスターが停止するなど)が発生した場合は、クラスタは停止するそうです。
また、通常のRedisと違ってTCPポートが2つ必要で、通常のRedisは(デフォルトで)6379ポートを使用しますが、
10000を追加したポート(例えば16379)を使用します。
このもうひとつのポートは、クラスタノード間での通信に使用され、障害検出、構成の更新、フェイルオーバーの許可
などといった用途で使用されます。このポートの通信を遮断すると、Redis Cluster内のノードがうまく通信できなくなります。
この10000というポートのオフセットは、固定みたいです。
スレーブについてですが、マスターとスレーブについてはきっちり役割がわかれているようなので、例えば
レプリカ数を1にすると、Redis Clusterを構成するにはマスター数×2のノードが必要になります。
3台分のデータを持ちたい時に、レプリカ数を1にすると、計6ノード必要になります、と。クラスタの構成時にレプリカ数を
指定するのですが、初期ノード数がこの計算を下回るとエラーになります。
けっこう、豪快な…。
環境
今回使用しているRedisは、5.0.2です。また、OSはUbuntu Linux 18.04 LTS。
サーバーは、Redis3台構成とします。IPアドレスの範囲は172.17.0.2〜4、ポートは標準の6379。
Redis自体は、ビルド・インストール済みとします。
各Redisサーバーの起動
サーバーそれぞれに、設定ファイルを用意。
conf/redis.conf
bind 0.0.0.0 port 6379 masterauth redispass cluster-enabled yes cluster-config-file conf/nodes.conf cluster-node-timeout 5000 appendonly yes
設定は、ドキュメントを見つつ。
Redis cluster tutorial – Redis
チュートリアルでは7000ポート以降を使用していますが、今回はデフォルトのポートをそのまま使うことにしました。
また、パスワードは「redispass」としています。
Redis Clusterに関する設定は、こちらを参照。
Redis Cluster configuration parameters
今回設定しているRedis Cluster関連のパラメーターは、「cluster-enabled」、「cluster-config-file」、「cluster-node-timeout」の
3つです。
設定のサンプルは、こちらを参照。
Creating and using a Redis Cluster
この設定で、各Redisサーバーを起動します。
## 172.17.0.2 $ bin/redis-server conf/redis.conf ## 172.17.0.3 $ bin/redis-server conf/redis.conf ## 172.17.0.4 $ bin/redis-server conf/redis.conf
クラスタを構成する
それでは、Redis Clusterを構成してみましょう。
$ bin/redis-cli --cluster create 172.17.0.2:6379 172.17.0.3:6379 172.17.0.4:6379 >>> Performing hash slots allocation on 3 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 M: fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379 slots:[0-5460] (5461 slots) master M: 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379 slots:[5461-10922] (5462 slots) master M: a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379 slots:[10923-16383] (5461 slots) master 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.17.0.2:6379) M: fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379 slots:[0-5460] (5461 slots) master M: 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379 slots:[5461-10922] (5462 slots) master M: a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379 slots:[10923-16383] (5461 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
クラスタが構成されました。
各ノードのログには、クラスタ構成時にこんな感じのログが出力されます。
9:M 25 Nov 2018 14:29:11.190 # configEpoch set to 3 via CLUSTER SET-CONFIG-EPOCH 9:M 25 Nov 2018 14:29:11.256 # IP address for this node updated to 172.17.0.4 9:M 25 Nov 2018 14:29:16.160 # Cluster state changed: ok
今回は3ノードで構成しようとしているので、例えば「--cluster-replicas」を1より大きくすると、レプリカを作るだけの
ノード数が足りなくなるので、コマンドの実行に失敗します。
$ bin/redis-cli --cluster create 172.17.0.2:6379 172.17.0.3:6379 172.17.0.4:6379 --cluster-replicas 1 *** ERROR: Invalid configuration for cluster creation. *** Redis Cluster requires at least 3 master nodes. *** This is not possible with 3 nodes and 1 replicas per node. *** At least 6 nodes are required.
つまり、今回の構成は耐障害性のない構成、すべてのノードがマスターノードとなっています。
ところで、以前はこのコマンドは「redis-trib.rb」というRubyスクリプトで行っていました。
Redis 5.0では、これがredis-cliで実行することが可能になっています。
少し前までは、クラスタのチュートリアルもredis-cliのみの内容になっていたのですが、最近になってredis-trib.rbの内容も
書くように修正されたみたいです。
Add info about redis-trib back into the Cluster tutorial.
Redis 4および3は、まだredis-trib.rbを使うからでしょうかね。
クラスタの情報を確認してみる
クラスタの情報を見てみましょう。「redis-cli」を使います。
$ bin/redis-cli cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:3 cluster_current_epoch:3 cluster_my_epoch:1 cluster_stats_messages_ping_sent:35 cluster_stats_messages_pong_sent:36 cluster_stats_messages_sent:71 cluster_stats_messages_ping_received:34 cluster_stats_messages_pong_received:35 cluster_stats_messages_meet_received:2 cluster_stats_messages_received:71
ノードの情報。
$ bin/redis-cli cluster nodes 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379@16379 master - 0 1543156193386 2 connected 5461-10922 a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379@16379 master - 0 1543156192383 3 connected 10923-16383 fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379@16379 myself,master - 0 1543156191000 1 connected 0-5460
この情報、設定項目「cluster-config-file」に記載された内容が出力されている感じがしますね。
$ cat conf/nodes.conf 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379@16379 master - 0 1543156151447 2 connected 5461-10922 a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379@16379 master - 0 1543156151447 3 connected 10923-16383 fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379@16379 myself,master - 0 0 1 connected 0-5460 vars currentEpoch 3 lastVoteEpoch 0
「redis-cli --cluster info」でも、似たような情報が得られます。
$ bin/redis-cli --cluster info 172.17.0.2:6379 172.17.0.2:6379 (fbf478e6...) -> 0 keys | 5461 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 0 keys | 5462 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 0 keys | 5461 slots | 0 slaves. [OK] 0 keys in 3 masters. 0.00 keys per slot on average.
「redis-cli --cluster」のヘルプは、「help」コマンドで確認できます。
$ bin/redis-cli --cluster help
Cluster Manager Commands:
create host1:port1 ... hostN:portN
--cluster-replicas <arg>
check host:port
info host:port
fix host:port
reshard host:port
--cluster-from <arg>
--cluster-to <arg>
--cluster-slots <arg>
--cluster-yes
--cluster-timeout <arg>
--cluster-pipeline <arg>
rebalance host:port
--cluster-weight <node1=w1...nodeN=wN>
--cluster-use-empty-masters
--cluster-timeout <arg>
--cluster-simulate
--cluster-pipeline <arg>
--cluster-threshold <arg>
add-node new_host:new_port existing_host:existing_port
--cluster-slave
--cluster-master-id <arg>
del-node host:port node_id
call host:port command arg arg .. arg
set-timeout host:port milliseconds
import host:port
--cluster-from <arg>
--cluster-copy
--cluster-replace
help
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
データを操作してみる
続いて、データを操作してみましょう。「redis-cli」で接続。
$ bin/redis-cli -h 172.17.0.2 -p 6379 172.17.0.2:6379>
なにも付けないと、キーの配置先によってはエラーになります。別のノードへのリダイレクトが必要になるからです。
172.17.0.2:6379> set key1 value1 (error) MOVED 9189 172.17.0.3:6379
これを回避する…自動でリダイレクトしてもらうには、「-c」オプションを付けます。
$ bin/redis-cli -h 172.17.0.2 -p 6379 -c 172.17.0.2:6379>
今度はOKです。
172.17.0.2:6379> set key1 value1 -> Redirected to slot [9189] located at 172.17.0.3:6379 OK 172.17.0.3:6379> set key2 value2 -> Redirected to slot [4998] located at 172.17.0.2:6379 OK 172.17.0.2:6379> set key3 value3 OK 172.17.0.2:6379> set key4 value4 -> Redirected to slot [13120] located at 172.17.0.4:6379 OK 172.17.0.4:6379> set key5 value5 -> Redirected to slot [9057] located at 172.17.0.3:6379 OK 172.17.0.3:6379> set key6 value6 -> Redirected to slot [4866] located at 172.17.0.2:6379 OK
よくよく見ると、リダイレクトがかかると接続先のノードが切り替わっていますね…。
キーの配置状況は、「redis-cli --cluster info」で見れるんですね。
172.17.0.2:6379 (fbf478e6...) -> 3 keys | 5461 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 2 keys | 5462 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 1 keys | 5461 slots | 0 slaves. [OK] 6 keys in 3 masters. 0.00 keys per slot on average.
ノードを追加する
今度は、少し方向を変えて、ノードを追加してみましょう。今のクラスタに、172.17.0.5というIPアドレスを持つノードを
追加してみます。
まずは、Redisを起動。
## 172.17.0.4 $ bin/redis-server conf/redis.conf
ノードを追加するには、「redis-cli --cluster add-node」を使用します。第1引数は新しいノード、第2引数は既存のノードです。
$ bin/redis-cli --cluster add-node 172.17.0.5:6379 172.17.0.2:6379 >>> Adding node 172.17.0.5:6379 to cluster 172.17.0.2:6379 >>> Performing Cluster Check (using node 172.17.0.2:6379) M: fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379 slots:[0-5460] (5461 slots) master M: 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379 slots:[5461-10922] (5462 slots) master M: a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379 slots:[10923-16383] (5461 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. >>> Send CLUSTER MEET to node 172.17.0.5:6379 to make it join the cluster. [OK] New node added correctly.
ノードが追加されました…がスロットが割り当てられていません。
$ bin/redis-cli --cluster info 172.17.0.2:6379 172.17.0.2:6379 (fbf478e6...) -> 3 keys | 5461 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 2 keys | 5462 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 1 keys | 5461 slots | 0 slaves. 172.17.0.5:6379 (7a796a7f...) -> 0 keys | 0 slots | 0 slaves. [OK] 6 keys in 4 masters. 0.00 keys per slot on average.
この状態でも、クライアントからのリクエストには応じることができるみたいですが。
$ bin/redis-cli -h 172.17.0.5 -p 6379 -c 172.17.0.5:6379> get key1 -> Redirected to slot [9189] located at 172.17.0.3:6379 "value1"
では、リシャードしましょう。「redis-cli --cluster reshard」で実行します。
$ bin/redis-cli --cluster reshard 172.17.0.2:6379 >>> Performing Cluster Check (using node 172.17.0.2:6379) M: fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379 slots:[0-5460] (5461 slots) master M: 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379 slots:[5461-10922] (5462 slots) master M: a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379 slots:[10923-16383] (5461 slots) master M: 7a796a7fb7c4e61699717acaa7d39ec8cb130581 172.17.0.5:6379 slots: (0 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)?
スロット(1〜16384)の範囲をどう動かすのか聞かれるので、今回は 16384 / 4で4096でいきます。
How many slots do you want to move (from 1 to 16384)? 4096
データを受け取るノードについて聞かれるので、今回追加したノードのIDを指定します。
What is the receiving node ID? 7a796a7fb7c4e61699717acaa7d39ec8cb130581
IDは、「redis-cli cluster nodes」などで確認してもいいですし、リシャードの実行時にも表示されていますね。
IDを指定すると、どのノードからデータを動かすか聞かれるので…今回は「all」を選んで全ノードから動かすようにします。
Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1: all
すると、リシャードのプランについての確認を求められるので
Ready to move 4096 slots.
Source nodes:
M: fbf478e684be17192c16a550bb4b85fa177262c2 172.17.0.2:6379
slots:[0-5460] (5461 slots) master
M: 33a5bbdb99f768cfd320867ed31292ab3107a26e 172.17.0.3:6379
slots:[5461-10922] (5462 slots) master
M: a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26 172.17.0.4:6379
slots:[10923-16383] (5461 slots) master
Destination node:
M: 7a796a7fb7c4e61699717acaa7d39ec8cb130581 172.17.0.5:6379
slots: (0 slots) master
Resharding plan:
Moving slot 5461 from 33a5bbdb99f768cfd320867ed31292ab3107a26e
Moving slot 5462 from 33a5bbdb99f768cfd320867ed31292ab3107a26e
Moving slot 5463 from 33a5bbdb99f768cfd320867ed31292ab3107a26e
Moving slot 5464 from 33a5bbdb99f768cfd320867ed31292ab3107a26e
Moving slot 5465 from 33a5bbdb99f768cfd320867ed31292ab3107a26e
...
Moving slot 12285 from a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26
Moving slot 12286 from a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26
Moving slot 12287 from a2ee1afd473c5a04ae88fdd84da4cc86e4aa1f26
Do you want to proceed with the proposed reshard plan (yes/no)?
「yes」と回答。
Do you want to proceed with the proposed reshard plan (yes/no)? yes
データの移動が始まります。
Moving slot 5461 from 172.17.0.3:6379 to 172.17.0.5:6379: Moving slot 5462 from 172.17.0.3:6379 to 172.17.0.5:6379: Moving slot 5463 from 172.17.0.3:6379 to 172.17.0.5:6379: Moving slot 5464 from 172.17.0.3:6379 to 172.17.0.5:6379: Moving slot 5465 from 172.17.0.3:6379 to 172.17.0.5:6379: ...
完了。各ノード、4096スロットずつ割り当てられるように、リシャードできました、と。
$ bin/redis-cli --cluster info 172.17.0.2:6379 172.17.0.2:6379 (fbf478e6...) -> 2 keys | 4096 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 2 keys | 4096 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 1 keys | 4096 slots | 0 slaves. 172.17.0.5:6379 (7a796a7f...) -> 1 keys | 4096 slots | 0 slaves. [OK] 6 keys in 4 masters. 0.00 keys per slot on average.
確認してみましょう。
$ bin/redis-cli -h 172.17.0.2 -p 6379 -c 172.17.0.2:6379> set key7 value7 -> Redirected to slot [803] located at 172.17.0.5:6379 OK
追加したノードにも、データが登録できました。
ノードを削除する
最後に、ノードを削除してみます。先ほど追加したノードを、クラスタから削除してみましょう。
ノードの削除は、「redis-cli --cluster del-node」で行います。対象のノードのIPアドレス、ポート、ノードのIDが必要です。
$ bin/redis-cli --cluster del-node 172.17.0.5:6379 7a796a7fb7c4e61699717acaa7d39ec8cb130581
ですが、これを実行すると、スロットが割り当てられているからかエラーになります。
bin/redis-cli --cluster del-node 172.17.0.5:6379 7a796a7fb7c4e61699717acaa7d39ec8cb130581 >>> Removing node 7a796a7fb7c4e61699717acaa7d39ec8cb130581 from cluster 172.17.0.5:6379 [ERR] Node 172.17.0.5:6379 is not empty! Reshard data away and try again.
では、リシャードしましょうか…。
$ bin/redis-cli --cluster reshard 172.17.0.2:6379 >>> Performing Cluster Check (using node 172.17.0.2:6379) M: d452b0232e6acb296deb78b09e6bc244f81f0ac7 172.17.0.2:6379 slots:[1365-5460] (4096 slots) master M: f97cb7a053f25161a2367a7ed6c107d2d6129065 172.17.0.4:6379 slots:[12288-16383] (4096 slots) master M: 6bf112f4d510a5273f89cb6c99e261df492800c0 172.17.0.5:6379 slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master M: 2a166ae9825e03447f6d6d664f6c5e7d425bb11a 172.17.0.3:6379 slots:[6827-10922] (4096 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
移動するスロットは、削除するノードが持っている数なので、4096。
How many slots do you want to move (from 1 to 16384)? 4096
データを受け取るノードは、クラスタに残るノードを選び
What is the receiving node ID? fbf478e684be17192c16a550bb4b85fa177262c2
移動元となるノードは、削除対象とするノードを選びます。
Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1: 7a796a7fb7c4e61699717acaa7d39ec8cb130581
2つ目以降にデータの移動元となるノードはないので、「done」。
Source node #2: done
リシャードのプランが表示されるので、問題がなければ「yes」。
Do you want to proceed with the proposed reshard plan (yes/no)? yes
今度は、ノードを削除できます(スロットの配置状況を確認するの忘れた…)。
$ bin/redis-cli --cluster del-node 172.17.0.5:6379 7a796a7fb7c4e61699717acaa7d39ec8cb130581 >>> Removing node 7a796a7fb7c4e61699717acaa7d39ec8cb130581 from cluster 172.17.0.5:6379 >>> Sending CLUSTER FORGET messages to the cluster... >>> SHUTDOWN the node.
そして、削除したノードはシャットダウンします…。
9:M 25 Nov 2018 14:38:54.822 # User requested shutdown... 9:M 25 Nov 2018 14:38:54.822 * Calling fsync() on the AOF file. 9:M 25 Nov 2018 14:38:54.827 # Redis is now ready to exit, bye bye...
クラスタから、ノードがいなくなりましたね。
$ bin/redis-cli --cluster info 172.17.0.2:6379 172.17.0.2:6379 (fbf478e6...) -> 4 keys | 8192 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 2 keys | 4096 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 1 keys | 4096 slots | 0 slaves. [OK] 7 keys in 3 masters. 0.00 keys per slot on average.
削除したノードが持っていたデータも、取得可能です。
$ bin/redis-cli -h 172.17.0.2 -p 6379 -c 172.17.0.2:6379> get key7 "value7"
ところで、スロットの配分を見ると、ものすごくバランスが悪いです…。
$ bin/redis-cli --cluster info 172.17.0.2:6379 172.17.0.2:6379 (fbf478e6...) -> 4 keys | 8192 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 2 keys | 4096 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 1 keys | 4096 slots | 0 slaves. [OK] 7 keys in 3 masters. 0.00 keys per slot on average.
リバランスしましょう。
$ bin/redis-cli --cluster rebalance 172.17.0.2:6379 >>> Performing Cluster Check (using node 172.17.0.2:6379) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. >>> Rebalancing across 3 nodes. Total weight = 3.00 Moving 1366 slots from 172.17.0.2:6379 to 172.17.0.3:6379 ###################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################### Moving 1365 slots from 172.17.0.2:6379 to 172.17.0.4:6379 #####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################
スロットのリバランスが完了、です。
$ bin/redis-cli --cluster info 172.17.0.2:6379 172.17.0.2:6379 (fbf478e6...) -> 2 keys | 5461 slots | 0 slaves. 172.17.0.3:6379 (33a5bbdb...) -> 4 keys | 5462 slots | 0 slaves. 172.17.0.4:6379 (a2ee1afd...) -> 1 keys | 5461 slots | 0 slaves. [OK] 7 keys in 3 masters. 0.00 keys per slot on average.
まとめ
Redis 5.0で、クラスタを構成したり、操作をいくつかやってみました。
今回は手動でノードを削除したりしましたが、こういう手順を介さずにノードを停止するようなケースなども
どこかでまた試してみたい?かも?