Redisクラスターのデータシャーディングメカニズム

高度な開発者が理解する必要があるRedisクラスターのデータシャーディングメカニズム

Redisクラスターの概要

Redis ClusterはRedisの分散ソリューションであり、バージョン3.0で正式にリリースされ、Redisの分散ニーズを効果的に解決しました。

通常、Redisクラスターは複数のノードで構成され、完全な高可用性クラスターを確保するにはノード数が少なくとも6でなければなりません。そのうち3つはマスターノードで、3つはスレーブノードです。3つのマスターノードは、クライアントのコマンド要求を処理するためのスロットを割り当て、マスターノードに障害が発生した後、スレーブノードを使用してマスターノードを置き換えることができます。

 

 

上の図に示すように、クラスターには6つのRedisノード、3つのマスター、および3つのスレーブ、つまりM1、M2、M3、S1、S2、S3が含まれています。すべてのRedisノードは、マスターとスレーブのRedisノード間のデータレプリケーションに加えて、Gossipプロトコルを使用してノードのメタデータ情報を通信および交換し、維持します。

一般的に、マスターRedisノードはクライアントの読み取りおよび書き込み操作を処理しますが、スレーブノードは読み取り操作のみを処理します。

データシャーディング戦略

分散データストレージソリューションの最も重要なポイントは、シャーディングとも呼ばれるデータシャーディングです。

クラスターを水平方向にスケーリングできるようにするために、解決すべき最初の問題は、特定のルールに従ってデータセット全体を複数のノードに分散する方法です。一般的なデータシャーディング方法には、範囲シャーディング、ハッシュシャーディング、および一貫性ハッシュがあります。アルゴリズムと仮想ハッシュスロット。

範囲分割では、データセットが順序付けされていると想定し、データを近い順序で並べることで、トラバーサル操作を適切にサポートできます。範囲シャーディングの欠点は、順次書き込むときにホットスポットがあることです。たとえば、ログタイプの書き込み、一般的なログの順序は時間に関連し、時間は単調に増加するため、書き込みのホットスポットは常に最後のシャードにあります。

 

 

リレーショナルデータベースの場合、テーブルスキャンまたはインデックススキャンが頻繁に必要になるため、基本的にはさまざまなシャーディング戦略を使用します。

Redisクラスターは仮想ハッシュスロット分割を使用します。すべてのキーは、ハッシュ関数に従って0〜16383の整数スロットにマッピングされます。計算式は、slot = CRC16(key)&16383です。各ノードは、スロットの一部とスロットによってマップされたキー値データを維持する責任があります。

Redis仮想スロットパーティションの機能:

  • データとノード間の関係を分離することで、ノードの拡張と縮小の難しさが簡素化されます。
  • ノード自体はスロットマッピング関係を維持し、スロットパーティションメタデータを維持するためにクライアントまたはプロキシサービスを必要としません
  • ノード、スロット、キー間のマッピングクエリをサポートし、データルーティング、オンラインクラスタースケーリング、その他のシナリオに使用されます。

 

 

Redisクラスターは、柔軟なノード拡張および縮小ソリューションを提供します。クラスターの外部サービスに影響を与えずに、クラスターにノードを追加して容量を拡張するか、オフラインにして容量を減らすことができます。スロットはRedisクラスター管理データの基本単位であると言えます。クラスタースケーリングは、ノード間のスロットとデータの移動です。

まず、Redisクラスタースケーリングの原理を見てみましょう。次に、Redisノードのデータ移行プロセス中または障害が回復したときにクラスターを確実に使用できるようにする方法を理解します。

拡張クラスター

読者がオンラインになったときの容量拡張操作をよりよく理解できるように、Redis Clusterコマンドを使用してプロセス全体をシミュレートします。

 

 

新しいRedisノードが実行され、既存のクラスターに参加する場合、そのためのスロットとデータを移行する必要があります。まず、新しいノードの移行計画を指定して、移行後に各ノードが同じ数のスロットを担当するようにして、これらのノードのデータを統一する必要があります。

1)最初にM4として示されるRedisノードを起動します。 
2)cluster meetコマンドを使用して、新しいRedisノードをクラスターに追加します。最初は、新しいノードはマスターノードの状態にあります。責任がある>スロットがないため、読み取りおよび書き込み操作を受け入れることができません。後でスロットを移行して、データを入力します。
3)cluster setslot {slot} importing {sourceNodeId}コマンドをM4ノードに送信して、ターゲットノードがスロットデータをインポートする準備をします。> 4)cluster setslot {slot} migrating {targetNodeId}コマンドをソースノード、つまりM1、M2、およびM3ノードに送信して、ソースノードの>ポイントがスロットデータから移動できるようにします。 
5)ソースノードはcluster getkeysinslot {slot} {count}コマンドを実行してスロット{slot}に属するカウントキーを取得し、ステップ6の操作を実行してキー値データを移行します。
6)ソースノードでmigrate {targetNodeIp} "" 0 {timeout} keys {key ...}コマンドを実行して、取得したキーをパイプラインメカニズムを介してバッチでターゲットノードに移行します> migrateコマンドのバッチ移行バージョンはRedis 3.0にあります。 6以上で利用できます。
7)スロットの下のすべてのKey-Valueデータがターゲットノードに移行されるまで、手順5と6を繰り返します。 
8)クラスターのsetlot {slot} node {targetNodeId}コマンドをクラスター内のすべてのマスターノードに送信して、ターゲットノードに割り当てるスロットを通知します。スロットノードのマッピング変更がタイムリーに伝達されるようにするには、すべてのマスターノードをトラバースして送信し、移行したスロットを更新して新しいノードを実行する必要があります。

クラスターの縮小

ノードを縮小すると、Redisノードがオフラインになります。プロセス全体では、次の操作プロセスが必要です。

1)まず、オフラインノードに責任のあるスロットがあるかどうかを確認する必要があります。責任がある場合は、スロットを別のノードに移動して、ノードがオフラインになった後のクラスタースロット全体のノードマッピングの整合性を確保する必要があります。 
2)オフラインノードがスロットを担当しなくなった場合、またはスレーブノードである場合、オフラインノードを忘れるようにクラスター内の他のノードに通知でき、ノードの変更を忘れた後、すべてのノードを正常にシャットダウンできます。

オフラインノードは、独自のスロットを他のノードに移行する必要があります。原理は、以前のノード拡張の移行スロットプロセスと同じです。

 

 

スロットを移行した後、オフラインにするのを忘れたことをクラスター内のすべてのノードに通知する必要もあります。つまり、他のノードは、オフラインになるノードとGossipメッセージを交換しなくなります。

Redisクラスターはcluster forget {downNodeId}コマンドを使用して、指定されたノードを禁止リストに追加します。禁止リスト内のノードは、ゴシップメッセージを送信しなくなりました。

クライアントのルーティング

クラスターモードでは、Redisノードは、キー関連のコマンドを受信すると、最初にキーに対応するスロットを計算し、次にスロットに従って対応するノードを見つけます。ノードがそれ自体の場合は、キーコマンドを処理します。それ以外の場合は、MOVEDリダイレクトエラーを返し、クライアントに通知します正しいノードをリクエストしてください。このプロセスはMOVEDリダイレクトと呼ばれます。

Redisはスロットを計算するときにキーコンテンツを単純に計算するのではなく、キー値に中括弧が含まれている場合は、大括弧内のコンテンツのみが計算されることに注意してください。たとえば、キーがuser:{10000}:本の場合、ハッシュ値に対して計算されるのは10000だけです。

MOVEDエラーの例では、次の情報が表示されます。キーxが属するハッシュスロットは3999であり、このスロットの処理を担当するノードのIPおよびポート番号は127.0.0.1:6381です。クライアントは、このIPとポート番号に基づいて、所属するノードにGETコマンド要求を送信する必要があります。

1
< code  class="hljs"></ code >

リクエストのリダイレクトによりIOオーバーヘッドが増加するため、これはRedisクラスターを使用する効率的な方法ではなく、スマートクラスタークライアントを使用する方法です。スロットとRedisノード間のマッピング関係を内部で維持することにより、スマートクライアントはキーからノードへのルックアップをローカルで実現できるため、IO効率の最大化を確実にし、MOVEDリダイレクトはクライアントがマッピング関係を更新するのを支援します。

Redisクラスターはオンライン移行スロットとデータをサポートし、水平スケーリングを完了します。スロットに対応するデータがソースノードからターゲットノードに移行されるとき、クライアントはインテリジェントな移行を実行して、キーコマンドが正常に実行されるようにする必要があります。たとえば、スロットデータがソースノードからターゲットノードに移行されると、一部のデータがソースノードとターゲットノードの別の部分に表示される場合があります。

 

 

したがって、上記の状況に基づいて、クライアントコマンドの実行プロセスは次のようになります。

  • クライアントはローカルスロットキャッシュに従ってコマンドをソースノードに送信し、キーの対応がある場合、クライアントは直接実行して結果をクライアントに返します。
  • ノードがMOVEDエラーを返した場合は、ローカルスロットのRedisノードへのマッピングを更新してから、リクエストを再開してください。
  • データが移行されている場合、ノードはASKリダイレクト例外で応答します。形式は次のとおりです:(エラー)ASK {slot} {targetIP}:{targetPort}

クライアントはASKリダイレクト例外からターゲットノード情報を抽出し、要求コマンドをターゲットノードに送信してクライアント接続識別子を開き、次にキーコマンドを実行します。

ASKとMOVEDはどちらもクライアントのリダイレクトを制御しますが、基本的には異なります。ASKリダイレクトは、クラスターでスロットデータの移行が行われていることを示します。クライアントは、移行がいつ完了したかを認識できないため、一時的なリダイレクトにすぎません。クライアントは、スロットのマッピングキャッシュをRedisノードに更新しません。ただし、MOVEDリダイレクトは、キーに対応するスロットが新しいノードに明示的に割り当てられていることを示しているため、スロットからRedisノードへのマッピングキャッシュを更新する必要があります。

フェイルオーバー

Redisクラスター内の少数のノードで障害が発生した場合、自動フェイルオーバーを使用して、クラスターが外部に正常にサービスを提供できるようにします。

Redisノードが客観的にオフラインになると、Redisクラスターはスレーブノードから1つを選択して置き換え、クラスターの高可用性を確保します。このコンテンツはこの記事のコアコンテンツではありません。興味のある学生は自分で学ぶことができます。

ただし、注意すべきことが1つあります。デフォルトでは、クラスターの16384スロットのいずれかがノードに割り当てられていない場合、クラスター全体は使用できません。キーコマンドを実行すると、CLUSTERDOWN Hash slot not serveコマンドが返されます。スロットを保持しているマスターノードがオフラインになると、クラスター全体が障害検出から転送の自動完了まで使用できなくなります。ほとんどのビジネスでは、この状況は耐えられないため、パラメーターcluster-require-full-coverageをnoに構成することをお勧めします。マスターノードに障害が発生した場合、そのマスターノードが担当するスロットの関連コマンドの実行にのみ影響し、他のマスターノードの可用性には影響しません。

おすすめ

転載: www.cnblogs.com/xiaozengzeng/p/12682496.html