redis clusterを構築する際は、redis-tribという便利なツールがありますが、ここではredis-tribを使わずに自力でclusterを構築する手順を書きます。
※redis-tribを使った方が安全に、簡単に構築できますし、いろんな機能があるのでちゃんと作るときはredis-tribを使うのを強く推奨します。
redisを3台起動する
[redis clusterの作り方]を参考に3台起動してください。(参照先URLの手順は3まで行います)
ここでは7000~7002 portを使って3台でクラスタを構築します。
redis.confにてcluster-enabled yes
とするとcluster-config-file
に設定されたファイル名のクラスタ設定ファイルが作られます。
ただ起動しただけだと、こんな感じ
2e6a31d530b15d79cf2bf58550899a7073ca5704 :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0
#SLOTの計算
redis clusterはキーのHASH値を元にデータが分配されます。GETやSETをした時は、キーのHASH値からどのノードにほしい情報が入っているか探し、そのノードへリダイレクトします。
それぞれのノードがどのHASH値のバリューを持つかを指定するのがSLOTです。
ここでは、各ノードが持つSLOT(HASH値)を計算します。
redis clusterのHASHの最大値は16383
今回は3台でクラスタを構築するので、それぞれのノードが持つSLOTの範囲は、16383 / 3 = 5461
となります。
つまり、
ノード | SLOTの範囲 |
---|---|
7000 | 0 ~ 5461 |
7001 | 5462 ~ 10922 |
7002 | 10933 ~ 16383 |
SLOTの割り当て
各ノードにSLOTを割り当てていきます。SLOTの割り当てにはCLUSTER ADDSLOTS コマンドを使用します。
例えば0番のSLOT一つを割り当てるときは、
$ redis-cli -p 7000 CLUSTER ADDSLOT 0
OK
とします。
ただ、CLUSTER ADDSLOTSコマンド`は一つずつしかSLOTを割り当てられない(←たぶん)ので、さすがに手作業で16383はきつい。
ということで、以下のコマンドで入れました。
CLUSTER ADDSLOTS 1 2 3 4 ..
とすることで1コマンドで複数のSLOTを割り当てることができます。
とわいえ、全部列挙するのはつらいので、以下のコマンドをお使いください。
$ for slot in `seq 0 5461`;
do
redis-cli -p 7000 CLUSTER ADDSLOTS $slot; > /dev/null
# 進捗状況を定期的に表示する
if [ $(($slot % 1000)) == 0 ]; then
echo '$slot: '$slot
fi
done
上記のような感じで他のノードへもSLOTを割り当てます。
SLOTを割り当てた後のnodes.confの状態
2e6a31d530b15d79cf2bf58550899a7073ca5704 :7000 myself,master - 0 0 0 connected 0-5461
vars currentEpoch 0 lastVoteEpoch 0
一行目の一番右が0-5461
となっているのが7000 portのノードが割り当てられているSLOTです。
0番~5461番
までというのを示しています。
連番ではなく飛び飛びのSLOTを割り当てると?
今回はSLOTを連番で割り当てたので、nodes.confは0-5461
という風になります。なので、redisのSLOTはもしかして連番でないと割り当てられない?と思ったので試してみました。
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 :7001 myself,master - 0 0 0 connected 5462 5464
vars currentEpoch 0 lastVoteEpoch 0
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 :7001 myself,master - 0 0 0 connected 5462-5464
vars currentEpoch 0 lastVoteEpoch 0
ということで、連番の時だけXXX-YYY
という形式になるんですねー
すべてのSLOTを割り当てた後のnodes.conf
7000, 7001, 7002すべてのノードにSLOTを割り当てたとのnodes.confの状態は以下のようになります。
2e6a31d530b15d79cf2bf58550899a7073ca5704 :7000 myself,master - 0 0 0 connected 0-5461
vars currentEpoch 0 lastVoteEpoch 0
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 :7001 myself,master - 0 0 0 connected 5462-10922
vars currentEpoch 0 lastVoteEpoch 0
87651510d1a7e22eb8282a027e03f56486eaf9f5 :7002 myself,master - 0 0 0 connected 10923-16383
vars currentEpoch 0 lastVoteEpoch 0
クラスタリング
SLOTの割り当てが終わったので、次は3台をつなげるクラスタリングをします。
クラスタリングでは「ある基点となるノード一台(基点ノード)を決めて、そのノード以外から基点ノードへ接続要求を出す」という感じでつなぎます。
ノード | 役割 |
---|---|
7000 | 基点ノード |
7001 | 接続要求を7000に出す |
7002 | 接続要求を7000に出す |
CLUSTER MEET
クラスタリングの接続要求はCLUSTER MEET <ノードのIP> <ノードのPort>コマンド
を使用します。
まずは、7001 portのノードから7000 portのノードへCLUSTER MEET
を送ります。
$ redis-cli -p 7001 CLUSTER MEET 127.0.0.1 7000
OK
そうするとnodes.confの状態は、
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 127.0.0.1:7001 master - 0 1422498533660 1 connected 5462-10922
2e6a31d530b15d79cf2bf58550899a7073ca5704 127.0.0.1:7000 myself,master - 0 0 0 connected 0-5461
vars currentEpoch 1 lastVoteEpoch 0
2e6a31d530b15d79cf2bf58550899a7073ca5704 127.0.0.1:7000 master - 0 1422498533152 0 connected 0-5461
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 127.0.0.1:7001 myself,master - 0 0 1 connected 5462-10922
vars currentEpoch 1 lastVoteEpoch 0
となり、それぞれのnodes.confへ一つエントリが増えたことがわかります。
そして、7002 portのノードから7000 portのノードへCLUSTER MEET
を送ります。
$ redis-cli -p 7002 CLUSTER MEET 127.0.0.1 7000
OK
最終的にnodes.confは以下のようになります。
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 127.0.0.1:7001 master - 0 1422498614878 1 connected 5462-10922
2e6a31d530b15d79cf2bf58550899a7073ca5704 127.0.0.1:7000 myself,master - 0 0 2 connected 0-5461
87651510d1a7e22eb8282a027e03f56486eaf9f5 127.0.0.1:7002 master - 0 1422498614207 0 connected 10923-16383
vars currentEpoch 2 lastVoteEpoch 0
ちなみに、CLUSTER INFO
の結果は、
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:2
cluster_my_epoch:1
cluster_stats_messages_sent:253
cluster_stats_messages_received:253
となります。
動作確認
CLUSTER INFO
のcluster_state
もok
となっていますし、なんとなくredis clusterができたっぽいところで、
簡単に動作確認をしてみます。
クラスタに対してredis-cliをするときは-cオプションを忘れずに
$ redis-cli -c -p 7000
127.0.0.1:7000> set num:1 1
-> Redirected to slot [15698] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set num:2 2
-> Redirected to slot [3377] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get num:1
-> Redirected to slot [15698] located at 127.0.0.1:7002
"1"
リダイレクトもされて、ちゃんと動くことが確認できました。
redis-trib.rb create
を使った時と同じことができました。