redisクラスタの構築と分析


概要


redisは、keyに対するshadingを提供するための無中心化モードを提供する、データ記憶を提供するmasterノードとmasterノードとの間で対等であり、masterノードとmasterノードとの間でgossipプロトコルにより通信を行い、クラスタ選択者、失効遷移、データ遷移のトリガなどの動作を実現する.

1.redisクラスタ構築


1.1構成項目の説明


cluster-enabled:クラスタモードをオンにするかどうか、yesがオンになり、noがオンになりません.cluster-config-file:クラスタ情報用のクラスタプロファイルであり、ユーザはファイルを編集または変更できない.cluster-node-timeout:クラスタ内のmasterノードの失敗最大時間を検出し、masterノードがこの時間を超えても連絡が取れない場合、バックアップノードがある場合、バックアップノードはmaserノードに対して失効移行し、いくつかがない場合はmasterノードが失効し、クラスタ内の多くのmasterノードが失効する場合、クラスタは操作を提供しない.cluster-slave-validity-factor:masterノードがタイムアウトを検出する最大接続再試行回数は、デフォルトでは0、つまりタイムアウトが検出されるとslaveノードがmasterに対して失効移行し、この値が正数の場合、factor*timeoutの時間周期内にslaveがmasterに対して失効移行することはない.cluster-migration-barrier:masterノードは接続の最小slaveノード数を保存する.cluster-require-full-coverage:プライマリノードが無効になったときにサービスを提供し続けるかどうか、デフォルトyes、すなわちプライマリノードが無効になったときにサービスを提供しない、no、無効になったときにサービスを提供する.

1.2クラスタ構築


次に,3マスタ3スレーブのクラスタを構築し,マスタノードポートはそれぞれ7000,7001,70002,スレーブノードポートは7003,7004,7005である.すなわち、1つのmasterノードが1つのslaveノードに対応する.プロファイルを作成するには、次の手順に従います.
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes

ポート名の6つのフォルダを作成し、プロファイルを各フォルダにコピーし、ポートを対応するエンドに変更します.
mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

redis-server実行プログラムを各フォルダにコピーし、起動します.
cd 7000
../redis-server ./redis.conf

実行後の結果は次のとおりです.
14073:M 11 Aug 14:45:40.198 * No cluster configuration found, I'm 5714dd95e99999f7130eba44747f7a15aa8f5394

5714 dd 95 e 99999 f 7130 eba 44747 f 7 a 15 aa 8 f 5394は、ノードIdを表す.
クラスタの作成:以上の手順を完了すると、各ノードは独立して実行され、クラスタは形成されません.次に、互いに通信し、クラスタを構成する必要があります.ここでは、redisが持参したツールredis-tribを使用して、まずredis gemをインストールします.
gem install redis

クラスタの作成
./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.0.1:7004 127.0.0.1:7005

作成成功
[OK] All 16384 slots covered

クラスタのステータスを表示するには、次の手順に従います.
127.0.0.1:7002> cluster nodes
4406983653bd90043b5b7f65af0afc571bb2d93c 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383
fd5e7a729072b0e7e29ff5a4935a0151c470a47d 127.0.0.1:7005 slave 4406983653bd90043b5b7f65af0afc571bb2d93c 0 1470899978447 3 connected
5714dd95e99999f7130eba44747f7a15aa8f5394 127.0.0.1:7000 master - 0 1470899976944 1 connected 0-5460
aca053afafd21f887d3bc9d87c16597f67b7e513 127.0.0.1:7001 master - 0 1470899977946 2 connected 5461-10922
c450ae75e23a2cfeda901c0de77ef0cae85a8a8b 127.0.0.1:7003 slave 5714dd95e99999f7130eba44747f7a15aa8f5394 0 1470899978947 1 connected
576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 127.0.0.1:7004 slave aca053afafd21f887d3bc9d87c16597f67b7e513 0 1470899977445 5 connected

コマンドテスト:
./redis-cli -c -p 7000
127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
127.0.0.1:7000>
127.0.0.1:7000> get hello
"world"
127.0.0.1:7000> get foo
-> Redirected to slot [12182] located at 127.0.0.1:7002
"bar"

クラスタ構築に成功

2.slotsマッピングの説明


redis内部には16384個のスロットが設けられ、各ノードは固定スロット数を割り当て、すなわち1つのクラスタは最大16348個のノードをサポートし、A,B,Cの3つのノードがあれば、以下のように割り当てられる.
    Node A  [0,5500]
    Node B [5501,11000]
    Node C [11001,16383]

1つのkeyについては、まずcrc 16を行い、結果を16384に対してモデリングし、得られた結果はkeyが属するスロットを表し、スロットの割り当てポリシーを照会することによってkeyが割り当てるサーバを得て、keyのクラスタ内部shadingを実現する.

3.リダイレクトコマンド


movedリダイレクトコマンド:クライアント側がredisクラスタのいずれかのノードと接続を確立した後、keyを操作する場合:コマンドを受信したredisノードがkeyに対応するスロットが自分の処理に属していないことを発見すると、clientにmovedエラーを返信し、スロットのある真のノードに戻り、client側がmovedエラーを受信した後、指定したノードにリダイレクトして操作する.いずれのredisノードも、クラスタ内の他のノードスロット対応情報を保持する.また、クライアントのパフォーマンスを向上するために、クライアントはスロットとサーバとの対応情報をキャッシュするので、movedが指向すると、キャッシュが更新される.
askリダイレクトコマンド:askリダイレクト送信クラスタ内でスロット対応keyをデータマイグレーションしている場合、具体的な流れは、client側がノードnodeAにkey 1の処理コマンドを送信する場合、Aノードがkey 1に対応するスロットslot 1の処理権を有し、key 1がnodeAで問い合わせることができず、slot 1がマイグレーション状態にある場合、nodeAはaskリダイレクトコマンドに戻り、マイグレーション対象ノードnodeBclientにリダイレクトコマンドを受信すると、NodeBにaskingコマンドを送信、key 1の処理コマンドを送信する.NodeBは、askingコマンドを受信と、slot 1がnodeB処理に該当しないことを発見するもkey 1の処理コマンドを実行する後続のコマンドに対して特殊な処理を行う.askが指向コマンドからクライアント側にキャッシュを更新することはなく、nodeBは一度だけ処理する.

4.フェイルオーバー


redisクラスタは、マスターノードのすべてのデータバックアップをslaveノードが保存するマスターノードを実行するメカニズムがあり、マスターノードが失効すると、slaveノードはマスターノードを失効移行する.具体的には、クラスタ内のマスターノード間で定期的に通信が行われ、クラスタ内の対等なマスターAノードがあるノードのマスターBのタイムアウトに応答していないことを発見すると、そのマスターBノードをfalingに設定、検出された状況をブロードキャストする.同時にmasterAは、クラスタ内の他のmasterノードのmasterBに対する検出結果を記録する、クラスタ内の大部分(n/2+1)のmasterノードがそのノードfalingと考えていることが判明した場合、masterBの装置をfailed、すなわち失効させ、同時にmasterAはmasterBのslaveノードにコマンドを送信選挙させる.選挙時には、n/2+1以上の投票が新しいmasterになるか、タイムアウトするかの2つのケースが1つの時間紀元内に存在する.選択に成功したslaveはmasterノードとなり、作業を継続し、タイムアウトは新しいmasterが選択されるまで新しい選挙に入る.ここで投票権を持つmasterは1回しか投票できないので、1つのmasterだけが当選することを保証する.失効したmasterノードが再オンラインになるとslaveノードに移行する.
redisクラスタのテスト結果は、上に構築したクラスタの7004が7001のslaveノードであり、7001を削除し、クラスタの状態を表示します.
127.0.0.1:7002> cluster nodes
4406983653bd90043b5b7f65af0afc571bb2d93c 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383
fd5e7a729072b0e7e29ff5a4935a0151c470a47d 127.0.0.1:7005 slave 4406983653bd90043b5b7f65af0afc571bb2d93c 0 1470903542509 3 connected
5714dd95e99999f7130eba44747f7a15aa8f5394 127.0.0.1:7000 master - 0 1470903542509 1 connected 0-5460
aca053afafd21f887d3bc9d87c16597f67b7e513 127.0.0.1:7001 master,fail - 1470903522089 1470903520389 2 disconnected
c450ae75e23a2cfeda901c0de77ef0cae85a8a8b 127.0.0.1:7003 slave 5714dd95e99999f7130eba44747f7a15aa8f5394 0 1470903541506 1 connected
576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 127.0.0.1:7004 master - 0 1470903543513 7 connected 5461-10922

7001が無効になったと同時に7004が新しいmasterノードになったことがわかる.
7001が再起動され、クラスタのステータスが表示されます.
127.0.0.1:7002> cluster nodes
4406983653bd90043b5b7f65af0afc571bb2d93c 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383
fd5e7a729072b0e7e29ff5a4935a0151c470a47d 127.0.0.1:7005 slave 4406983653bd90043b5b7f65af0afc571bb2d93c 0 1470903594126 3 connected
5714dd95e99999f7130eba44747f7a15aa8f5394 127.0.0.1:7000 master - 0 1470903596130 1 connected 0-5460
aca053afafd21f887d3bc9d87c16597f67b7e513 127.0.0.1:7001 slave 576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 0 1470903594727 7 connected
c450ae75e23a2cfeda901c0de77ef0cae85a8a8b 127.0.0.1:7003 slave 5714dd95e99999f7130eba44747f7a15aa8f5394 0 1470903595730 1 connected
576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 127.0.0.1:7004 master - 0 1470903595629 7 connected 5461-10922

7001はslaveノードとなる.

5.クラスタ拡張


クラスタ拡張は、新規ノード(masterノードの新規追加、slaveノードの新規追加を含む)と減少ノードの2つに分けられる.新しいmasterノードプロセスは、前にクラスタを構築するときと一致し、まずノードにポートを割り当てて7006などの実行を行う.次にredis-tribで次のコマンドを実行します.
./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

以上のように、1番目のアドレスは新規のアドレスであり、2番目のアドレスはクラスタ内ですでに実行されているマスターアドレスであり、以上のコマンドを実行した後、マスターはクラスタに参加したが、スロットに割り当てられてデータ処理を行う必要はなく、reshaingを行う必要があり、コマンドは以下の通りである.
./redis-trib.rb reshard --from  --to  --slots  --yes :

slaveノードの追加
./redis-trib.rb add-node --slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006 127.0.0.1:7000

このうち、master-idは誰になるかを示すslave.
ノードの削減
./redis-trib del-node 127.0.0.1:7000 ``

6.まとめ


プロセス全体から見るとクラスタの作成にしても後期クラスタのメンテナンスにしても、redisは非常にスムーズで、これは間違いなく使用の敷居を高め、現在のredisの性能では、redisキャッシュクラスタを作るのは良い選択ですが、運営環境で使用するには、より便利な配置とメンテナンスツールが必要です.ここでは、捜狐のオープンソースツールcachecloudをお勧めします.https://github.com/sohutv/cac...