LoginSignup
26
26

More than 5 years have passed since last update.

redis clusterを自力で構築してみた

Last updated at Posted at 2015-01-29

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に設定されたファイル名のクラスタ設定ファイルが作られます。
ただ起動しただけだと、こんな感じ

7000/nodes.conf
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の状態

7000/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はもしかして連番でないと割り当てられない?と思ったので試してみました。

5462番と5424番のSLOTを割り当ててた後のnodes.conf
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 :7001 myself,master - 0 0 0 connected 5462 5464
vars currentEpoch 0 lastVoteEpoch 0
さらに5463番を割り当てた後のnodes.conf
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の状態は以下のようになります。

7000のnodes.conf
2e6a31d530b15d79cf2bf58550899a7073ca5704 :7000 myself,master - 0 0 0 connected 0-5461
vars currentEpoch 0 lastVoteEpoch 0
7001のnodes.conf
0efa999a0f4a9acd7f4af505d8677246c93e8ae8 :7001 myself,master - 0 0 0 connected 5462-10922
vars currentEpoch 0 lastVoteEpoch 0
7002のnodes.conf
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の状態は、

7000/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
7001/nodes.conf
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は以下のようになります。

7000/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 INFOcluster_stateokとなっていますし、なんとなく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を使った時と同じことができました。

26
26
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
26