6 Redis分散システム
Redis 分散システムは、正式には Redis Cluster、Redis クラスターと呼ばれ、Redis 3.0 によって開始された分散ソリューションです。これにより、異なるデータを異なる Redis ノードに保存し、ユーザーのリクエストを異なる Redis にルーティングするという問題をうまく解決できます。
6.1 データ分割アルゴリズム
分散データベース システムは、異なるデータ パーティション アルゴリズムに従って異なるデータベース サーバー ノードにデータを分散して保存し、各ノードはデータ セット全体のサブセットを管理します。
一般的なデータ パーティショニング ルールには、シーケンシャル パーティショニングとハッシュ パーティショニングの 2 つがあります。
6.1.1 順次パーティショニング
シーケンシャル パーティショニング ルールにより、データを特定の順序でさまざまなノードに均等に分散できます。順序付け方法が異なると、分割アルゴリズムも異なります。たとえば、ラウンドロビン分割アルゴリズム、タイムスライスラウンドロビン分割アルゴリズム、データブロック分割アルゴリズム、ビジネストピック分割アルゴリズムなどです。これらのアルゴリズムは比較的単純であるため、ここでは説明しません。
6.1.1.1 ラウンドロビン分割アルゴリズム
データが生成されるたびに、そのデータは異なるノードに順番に割り当てられます。このアルゴリズムは、データの問題が不確実なシナリオに適しています。分散の結果、データの総量が非常に大きい場合、各ノードのデータは非常に平均的になります。ただし、プロデューサーとデータノード間の接続は長期間維持する必要があります。
6.1.1.2 タイムスライス回転分割アルゴリズム
固定長のタイムスライス内のデータがノードに割り当てられます。タイムスライスが終了すると、再生成されたデータが次のノードに分配されます。これらのノードは順番にローテーションされてデータが割り当てられます。アルゴリズムには不均一なノード データが含まれる可能性があります (各タイム スライスで生成されるデータの量が異なる可能性があるため)。ただし、プロデューサーとノード間の接続は現在使用中の接続のみを占有する必要があり、他の接続は使用後すぐに解放されます。
6.1.1.3 データブロック分割アルゴリズム
全体のデータの総量が決まると、各ノードの記憶容量に応じて、接続されたデータのブロック全体を特定のノードに割り当てることができます。
6.1.1.4 ビジネストピック分割アルゴリズム
さまざまなビジネステーマに応じて、データをさまざまなノードに割り当てることができます。
6.1.2 ハッシュパーティショニング
ハッシュ分割ルールは、データのハッシュ値を最大限に活用して分散を完了するものであり、データのハッシュ値の使用方法が異なれば、ハッシュ分割アルゴリズムも異なります。ハッシュ パーティション アルゴリズムは比較的複雑ですが、一般的なハッシュ パーティション アルゴリズムをいくつか紹介します。
6.1.2.1 ノードモジュラス分割アルゴリズム
このアルゴリズムの前提条件は、各ノードに一意のシーケンス番号が割り当てられており、N ノードを持つ分散システムの場合、シーケンス番号の範囲は [0, N-1] です。次に、データそのもの、またはデータの特徴を表現できるデータの一部をキーとして選択し、ハッシュ(キー)とノード数Nの剰余を計算し、計算結果がストレージのシリアル番号になります。データのノード。
このアルゴリズムの最大の利点はその単純さですが、重大な欠点もあります。分散システムが拡張または縮小した場合、保存されているデータは新しいノード数 N に応じて移行する必要があります。そうしないと、ユーザーはキーに基づいて元のデータを見つけることができなくなります。本番環境での拡張では、拡張時のデータ移行の割合を減らすため、2倍拡張方式を採用するのが一般的です。
6.1.2.2 一貫したハッシュ分割アルゴリズム
一貫性のあるハッシュ アルゴリズムは、一貫性のあるハッシュ リングと呼ばれるデータ構造を通じて実装されます。このリングの始点は 0、終点は 232 - 1 であり、始点と終点は一致します。リングの中央の整数は反時計回りに分布するため、このリングの整数分布範囲は [0, 232-1] になります。
上の図では、o1、o2、o3、o4 の 4 つのオブジェクトがあり、それぞれ割り当てられる 4 つのデータを表し、赤い四角はハッシュ リング内のこれら 4 つのデータの hash(o) のドロップ ポイントです。同時に、グラフ上には 3 つのノード m0、m1、m2 があり、緑色の円はハッシュ リング内のこれら 3 つのノードのハッシュ (m) のドロップ ポイントです。
次に、データを保存するノードにデータを割り当てます。データオブジェクトのハッシュ(o)は反時計回りでノードのハッシュ(m)に最も近く、データはノードに格納されます。これにより、上の図に示す分布が得られます。
このアルゴリズムの最大の利点は、ノードの拡張と縮小が反時計回りの方向でそのノードに最も近いノードにのみ影響し、他のノードには影響を及ぼさないことです。
ノードの数が少ない場合、データ スキューの問題が非常に発生しやすく、ノードの変更によって影響を受けるノードの数が大きな割合を占めます。つまり、影響を受けるデータの量が多くなります。したがって、この方法はデータ ノードが少ないシナリオには適していません。
6.1.2.3 仮想スロット分割アルゴリズム
このアルゴリズムでは、まず固定数の整数セットを仮想化し、セット内の各整数をスロットと呼びます。一般に、スロットの数はノードの数よりもはるかに多くなります。次に、すべてのスロットを平均して各ノードにマッピングします。たとえば、Redis 分散システムでは合計 16384 個のスロットが仮想化されており、範囲は [0, 16383] です。合計 3 つのノードがあると仮定すると、スロットとノード間のマッピング関係は次の図に示されています。
データはスロットにのみ関連しており、ノードには直接関連していません。データは、キーのハッシュ (キー) によってのみスロットにマップされます: スロット = ハッシュ(キー) % スロット数。これもアルゴリズムの利点であり、データとノードが分離されているため、クライアントはノードを維持する必要がなく、スロットとの関係を維持するだけで済みます。
このアルゴリズムは、Redis データのパーティショニングに使用されます。スロット ポイントの計算式は、スロット = CRC16(キー) % 16384 です。CRC16() は、検証機能と優れた分散機能を備えた特殊なハッシュ アルゴリズム関数です。実際、Redis でスロットを計算する式は上記のものではなく、slot = CRC16(key) &16383 です。
a % b を計算するには、b が 2 の累乗である場合、a % b = a & (b-1) となります。
6.2 システムの構築と運用
6.2.1 システム構築
6.2.1.1 システムアーキテクチャ
以下で構築するRedis分散システムは6つのノードで構成されており、各6つのノードのアドレスと役割は下表のとおりです。マスターにはスレーブが装備されていますが、マスターとスレーブのペア関係はシステム構築後に自動的に割り当てられます。
シリアルナンバー | 役割 | 住所 |
---|---|---|
1 | マスター | 127.0.0.1:6380 |
2 | マスター | 127.0.0.1:6381 |
3 | マスター | 127.0.0.1:6382 |
4 | 奴隷 | 127.0.0.1:6383 |
5 | 奴隷 | 127.0.0.1:6384 |
6 | 奴隷 | 127.0.0.1:6385 |
6.2.1.2 永続ファイルの削除
まず、以前の「Redisマスタースレーブクラスター」のRedisインストールディレクトリに生成されたRDB永続ファイルdump638*.confとAOF永続ファイルを削除します。Redis 分散システムでは空のデータベース上に作成する必要があるためです。すべての AOF 永続ファイルは appendonlydir ディレクトリにあることに注意してください。
6.2.1.3 ディレクトリの作成
Redis インストール ディレクトリに、分散システムの作業ディレクトリとして使用される新しいディレクトリ clusta-dis を mkdir します。
6.2.1.4 2 つの設定ファイルをコピーする
クラスター ディレクトリ内の redis.conf および redis6380.conf ファイルを、cluster-dis ディレクトリにコピーします。
6.2.1.5 redis.confを変更する
redis.conf 構成ファイルの場合、主に次の 3 つまたは 4 つの属性が関係します。
6.2.1.5.1 ディレクトリ
作業ディレクトリを、前に作成したcluster-disディレクトリとして指定します。永続化ファイルとノード構成ファイルは、将来、作業ディレクトリに自動的に生成されます。
6.2.1.5.2 クラスター対応
このプロパティは、Redis のクラスター モードを有効にするために使用されます。
6.2.1.5.3 クラスタ構成ファイル
このプロパティは、「クラスタノード」の設定ファイルを指定するために使用されます。このファイルはノードの初回起動時に自動的に生成され、生成されたパスは dir 属性で指定された作業ディレクトリにあります。クラスター ノード情報が変更されると (ノードのオフライン、フェイルオーバーなど)、ノードはクラスターのステータス情報を構成ファイルに自動的に保存します。
ただし、ここではプロパティはコメントされたままです。以下のノードごとに個別の構成ファイルで構成します。
6.2.1.5.4 クラスターノードタイムアウト
「クラスターノード」間の通信のタイムアウトしきい値をミリ秒単位で指定するために使用されます。
6.2.1.6 redis6380.confを変更する
クラスター構成ファイルのプロパティを追加するだけです。
6.2.1.7 5 つの設定ファイルをコピーする
redis6380.conf を使用して、5 つの構成ファイル redis6381.conf、redis6382.conf、redis6383.conf、redis6384.conf、redis6385.conf をコピーします。
cluster-dis には 7 つの構成ファイルがあります。
6.2.1.8 5 つの設定ファイルを変更する
5 つの構成ファイル redis6381.conf、redis6382.conf、redis6383.conf、redis6384.conf、および redis6385.conf の内容を変更し、現在のファイル名のポート番号に関連するすべてのポート番号を置き換えます。たとえば、redis6381.conf の構成ファイルの内容は次のとおりです。
6.2.2 システムの起動と終了
6.2.2.1 ノードの起動
すべての Redis ノードを起動します。
この時点でcluster-disディレクトリを確認すると、6ノード分の設定ファイルが生成されていることがわかります。
6.2.2.2 システムの作成
6 つのノードは起動後も 6 つの独立した Redis のままであり、redis-cli --cluster create コマンドを使用して 6 つのノードを含む分散システムを作成できます。
このコマンドは、指定した 6 つのノードを分散システムに接続するために使用されます。--cluster レプリカ 1 は、各マスターがコピーとしてスレーブを持つことを指定します。
Enter キーを押すと、すぐに次のログが表示されます。
「yes」と入力して Enter キーを押すと、システムは上に表示された動的構成情報を実際にノードに適用し、次のログが表示されます。
6.2.2.3 試験システム
クラスター ノード コマンドを使用すると、システム内の各ノードの関係と接続ステータスを表示できます。各ノードが接続されていることが確認できれば、分散システムの構築は成功です。ただし、クライアント接続コマンド redis-cli については、次の 2 点に注意する必要があります。
- redis-cli には -c パラメーターがあり、ノードではなく「クラスター」に接続することを示します。
- ポート番号は6つのいずれかを使用できます。
6.2.2.4 システムのシャットダウン
分散システムのシャットダウンは各ノードをシャットダウンするだけで済みます。
6.3 クラスタ運用
6.3.1 クラスターへの接続
分散システムをどのように運用する場合でも、まず接続する必要があります。
以前のスタンドアロン接続と比較した唯一の違いは、パラメーター -c が追加されていることです。
6.3.2 データの書き込み
6.3.2.1 単一キーの書き込み
値の型が String であっても、List や Set などのコレクション型であっても、書き込み時の操作がキーであれば、分散システムでは問題ありません。例えば、
6.3.2.2 キー一括操作
一度に複数のキーを書き込む操作では、複数のキーが複数のスロットを計算するため、複数のスロットが複数のノードに対応する可能性があります。一度に書き込めるノードは 1 つだけであるため、この操作ではエラーが報告されます。
ただし、システムは、バッチ キーの操作スキームも提供し、これらのキーの統一グループを指定し、このグループをスロットを計算するための唯一の値にします。
6.3.3 クラスタークエリ
6.3.3.1 キーのスロットを問い合わせる
指定されたキーのスロットは、クラスター キースロットを通じてクエリできます。たとえば、次は emp をクエリするスロットです。
6.3.3.2 スロット内のキーの数を問い合わせる
指定したスロットに含まれるキーの数を表示するには、cluster countkeysinslot コマンドを使用します。
6.3.3.3 スロット内のキーを問い合わせる
指定したスロットに含まれるキーを表示するには、cluster getkeysinslot コマンドを使用します。
6.3.4 フェイルオーバー
分散システム内のマスターがダウンすると、対応するスレーブが自動的にマスターに昇格します。元のマスターが再起動されると、元のマスターは自動的に新しいマスターのスレーブになります。
6.3.4.1 故障のシミュレーション
クラスター ノード コマンドを使用すると、システムの全体的な構造と接続ステータスを表示できます。
もちろん、情報レプリケーションを通じて現在のクライアントに接続されているノードの役割を表示することもできます。6381 ノードがマスターであり、そのスレーブが 6383 ノードであることがわかります。
6381 のダウンタイムをシミュレートするには、直接シャットダウンします。
クライアント経由で 6383 ノードに接続すると、ノードが自動的にマスターに昇格したことがわかります。
ノード 6381 を再起動した後、その役割を確認すると、自動的にノード 6383 のスレーブになることがわかります。
6.3.4.2 完全な適用要件
特定のスロット範囲に対応するノードのすべてのマスターとスレーブがダウンした場合、分散システム全体が引き続き外部読み取りサービスを提供できるかどうかは、cluster-require-full-coverage 属性の設定によって決まります。
この属性には 2 つの値があります。
- はい: デフォルト値。システムは、すべてのスロット ノードが完全にカバーされている場合にのみ実行できます。
- no: システムは、スロット ノードが不完全な場合にもクエリ サービスを提供できます。
6.3.5 クラスターの拡張
下面要在正在运行的分布式系统中添加两个新的节点:端口号为6386的节点为master节点,其下会有一个端口号为6387的slave节点。
6.3.5.1 2 つの設定ファイルをコピーして変更する
redis6380.conf を使用して、2 つの構成ファイル redis6386.conf および redis6387.conf をコピーし、各場所のポート番号を対応するポート番号に変更して、クラスター拡張の準備をします。
6.3.5.2 2ノードでシステムを起動する
これからデモするのは分散システムの運用中の動的拡張であるため、ここでは最初に分散システムを起動します。
追加する 2 つのノードは 2 つの Redis であるため、最初に起動する必要があります。ただし、分散システムに追加される前は、2 つのノードは分離されたノードであり、各ノードは他のノードとは何の関係もありません。
6.3.5.3 マスターノードの追加
新しいノードは、コマンド redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort} によってシステムに追加できます。ここで、{newHost}:{newPort} は新しく追加されたノードのアドレス、{existHost}:{existPort} は元のシステム内の任意のノードのアドレスです。
追加が成功すると、次のログが表示されます。
追加が成功した後、 redis-cli -c -p 6386 クラスター ノード コマンドを使用すると、他のマスター ノードにはスロットが割り当てられており、新しく追加されたマスターのみに対応するスロットがないことがわかります。もちろん、このコマンドを通じて新しいノードの動的 ID も確認できます。
6.3.5.4 スロットの割り当て
新しいマスターに割り当てられるスロットは他のノードからのものであり、スロットの合計数は変わりません。したがって、スロット割り当てプロセスは本質的にはスロットの移動プロセスである。
redis-cli –c --cluster reshard {existIP}:{existPort} コマンドを使用して、スロット割り当てプロセスを開始します。アドレス {existIP}:{existPort} は、分散システム内の任意のノードのアドレスです。
このプロセスでは、最初に現在のノードのスロット割り当てが照会されます。
次に、Q&A の対話を開始します。合計 4 つの質問がありましたが、ここでは 3 つを紹介します。
- スロットは何個移動しますか?
- モバイルスロットを受け取るのは誰ですか?
- スロットの移動元のソース ノードを選択します。選択肢は 2 つあります。「すべて」と入力することを選択した場合、既存のすべてのスロット ノードがスロット ソース ノードとして使用されます。つまり、このソリューションは大規模なスロットのグローバル割り当てを実行します。他の部分ノードをスロット ソース ノードとして選択することもできます。このとき、ここでソース ノードの動的 ID をコピーし、各 ID を入力した後で Enter を押し、次に次のスロット ソース ノードの動的 ID をコピーして、最後のものが完了するまで「done」と入力して Enter を押します。
ここでのタイプは、グローバルな大規模割り当て用の all です。
まず、指定されたスロット ソース ノードのデータを検出し、次にリシャード プランを策定します。
ここで別の Q&A 対話が行われ、推奨されるソリューションの作業を続行するかどうかを尋ねられます。「yes」と入力し、実際のグローバル割り当てを開始して完了します。
このとき、redis-cli -c -p 6386クラスタノードコマンドでノード情報を確認すると、6386ノードにスロットが割り当てられていますが、割り当てられたスロット番号が連続していないことがわかります。マスターノードが追加されました。
6.3.5.5 スレーブノードの追加
次に、6387 ノードを 6386 ノードのスレーブとして追加します。もちろん、まずは 6387 ノードの Redis が起動していることを確認してください。
redis-cli --cluster add-node {newHost}:{newPort} {existHost}:{existPort} --cluster-slave --cluster-master-id masterID コマンドを使用すると、新しく追加されたノードを指定されたマスタースレーブ。
Enter キーを押すと、追加が成功したことを示す次のログが表示されます。
この時点で、 redis-cli -c -p 6386 クラスター ノード コマンドを使用すると、クラスター ノードが正常に追加され、指定されたマスターのスレーブであることがわかります。
6.3.6 クラスターの縮小
次に、スレーブノード6387とマスターノード6386が分散システムから削除される。
6.3.6.1 スレーブノードの削除
スレーブ ノードの場合は、 redis-cli --cluster del-node : delNodeID コマンドを使用して直接削除できます。
この時点でクラスターを確認すると、6387 ノードがなくなっていることがわかります。
6.3.6.2 マスタースロットの取り外し
マスターを削除する前に、マスターにスロットが割り当てられていないことを確認する必要があります。そうしないと削除できません。したがって、マスターを削除する前に、マスターに割り当てられているスロットを削除する必要があります。
上記の対話は、6386 ノードの 1999 スロットが 6380 ノードに移動されることを指定します。
知らせ:
- 削除対象のノードに含まれるスロット数は前回の検出結果から確認できます(例:6386のスロット数は2000ではなく1999)
- 受信ノードIDとは何ですか? 受信ノードは1つだけ指定可能です
入力して続行します。
この時点でもう一度確認すると、6386 ノードにスロットがないことがわかります。
6.3.6.3 マスターノードの削除
この時点で、6386 ノードを削除できます。
この時点で、クラスターを再度確認すると、6386 ノードがないことがわかります。
6.4 分散システムの制限
Redis の分散システムにはいくつかの使用制限があります。
- データベース番号 0 のみがサポートされています
- バッチキー操作のサポートは制限されています
- パーティションはキーに限定されます
- 限定的なトランザクションのサポート
- 階層管理をサポートしていません