[Redis] Redis の高同時実行性と高可用性 (クラスター ソリューション)

Redis クラスター

Redis Cluster は Redis の分散ソリューションであり、バージョン 3.0 で正式にリリースされ、Redis の分散ニーズを効果的に解決します。単一マシンのメモリ、同時実行性、トラフィックなどのボトルネックが発生した場合、クラスター アーキテクチャ ソリューションを使用して負荷分散を実現できます。以前は、一般的に 2 種類の Redis 分散ソリューションがありました。

1. クライアント パーティショニング スキームの利点は、パーティショニング ロジックが制御可能であることですが、欠点は、データ ルーティング、高可用性、フェイルオーバーなどの問題に自分で対処する必要があることです。

2. エージェント ソリューションには、クライアントの分散ロジックが簡素化され、アップグレードとメンテナンスが容易になるという利点がありますが、アーキテクチャの展開が複雑になり、パフォーマンスが低下するという欠点があります。

現在、公式は、Redis クラスターの問題を非常にエレガントに解決する独自のクラスター ソリューションである Redis Cluster を提供しているため、Redis Cluster をよく理解して適用することで、分散 Redis を使用する際の作業負荷が大幅に解放されます。

クラスターの事前知識

データ分散理論

        分散データベースでは、まず、パーティショニング ルールに従ってデータ セット全体を複数のノードにマッピングする、つまりデータ セットを複数のノードに分割するという問題を解決する必要があり、各ノードはデータ全体のサブセットを担当します。

        注目する必要があるのは、データの分割ルールです。一般的なパーティショニングルールには、ハッシュパーティショニングとシーケンシャルパーティショニングがあり、ハッシュパーティショニングは分散が良く、データ配信業務とは無関係で、シーケンシャルにアクセスできない、シーケンシャルパーティショニングは分散が偏りやすい、データ配信業務に関係し、アクセスが困難である。順次アクセスされます。

ノードは残りのパーティションを取得します

Redis キーやユーザー ID などの特定のデータを使用し、式 hash(key)%N を使用してノード数 N に基づいてハッシュ値を計算し、データがどのノードにマップされるかを決定します。このソリューションには問題があります。ノードの拡大または縮小など、ノードの数が変化すると、データ ノードのマッピング関係を再計算する必要があり、データの再移行が発生します。

この方法の優れた利点はその単純さです。データベースやデータベースのテーブルの分割ルールでよく使用されます。一般的には、事前分割方法が使用されます。データ量に応じて事前に分割数を計画し、たとえば、将来の期間をサポートできるようにテーブルを 512 または 1024 のテーブルに分割し、負荷状況に基づいてテーブルを他のデータベースに移行します。容量を拡張する場合、図 10-2 に示すように、すべてのデータ マッピングが中断されて完全な移行が発生することを避けるために、通常は 2 倍の容量が使用されます。

一貫したハッシュパーティショニング

一貫性のあるハッシュ テーブル (分散ハッシュ テーブル) の実装のアイデアは、システム内の各ノードに、通常 0 から 23 の範囲のトークンを割り当てることです。これらのトークンはハッシュ リングを形成します。データの読み書きでノード検索を行う場合、まずキーに基づいてハッシュ値が計算され、時計回りにハッシュ値以上の最初のトークンノードが検索されます。例えば:

クラスターには 3 つのノード (Node1、Node2、Node3) と 5 つのキー (key1、key2、key3、key4、key5) があり、ルーティング ルールは次のとおりです。

画像.png

クラスターにノードが追加されたとき、たとえば、Node2 と Node3 の間にノード Node4 が追加されたとき、このときにノード key4 にアクセスすると、Node4 ではヒットできません。より一般的には、Node2 と Node4 の間のキーは無効です。 、そのような失敗方法は「集中的」かつ「暴力的」すぎるので、より良い方法は「スムーズ」かつ「分散」した失敗であるはずです。

画像.png

ノードの残りと比較したこの方法の最大の利点は、ノードの追加と削除がハッシュ リング内の隣接するノードにのみ影響し、他のノードには影響を与えないことです。しかし、一貫したハッシュ パーティショニングにはいくつかの問題があります。

1. 少数のノードを使用する場合、ノードの変更はハッシュ リング内のデータ マッピングに大規模な影響を与えるため、この方法はデータ ノードの数が少ない分散ソリューションには適していません。

2. ノードを追加すると、次に隣接するノードでのみ負荷分散効果が向上します。たとえば、上図のノード Node4 を追加すると、ノード 3 で負荷の一部を共有できるだけであり、基本的に、ノード内の他のノードには負荷分散効果がありません。 ;同様に、ノードを削除すると、次に隣接するノードの負荷が増加し、他のノードは負荷圧力を効果的に共有できなくなります。

コンシステント ハッシュ パーティショニングのこれらの欠点のため、一部の分散システムでは、仮想コンシステント ハッシュ パーティショニングなど、仮想スロットを使用してコンシステント ハッシュを改善しています。

仮想一貫性のあるハッシュ パーティショニング

画像.png

ノードの追加または削除時にノード間の動的なバランスを維持するために、各実ノードは複数の仮想ノードに仮想化され、これらの仮想ノードはリングにランダムにマッピングされます。現時点では、各実ノードはリングにマッピングされておらず、実ノードはキーと値のペアを保存するためにのみ使用され、リング上で独自の仮想ノードのセットを接続する役割を果たします。キーと値のペアにアクセスしてルーティングする場合、キーと値のペアはまず仮想ノードにルーティングされ、次に仮想ノードが実際のノードを見つけます。

次の図に示すように、3 つの実ノード (Node1、Node2、Node3) があり、各実ノードは 3 つの仮想ノード (X#V1、X#V2、および X#V3) を仮想化するため、各実ノードがハッシュ空間を担当します。もはや連続セクションではありませんが、リング全体に分散されているため、局所的な圧力をさまざまなノードにバランスさせることができます。仮想ノードの数が多いほど、分散が向上し、理論的には負荷がより均一になります。

仮想スロットパーティション

Redis は、仮想スロット パーティショニングを使用します。これは、上記の仮想コンシステント ハッシュ パーティショニングの変形と考えることができます。分散性の高いハッシュ関数を使用して、すべてのデータを固定範囲の整数セットにマッピングします。整数はスロットとして定義されます。この範囲は通常、ノードの数よりもはるかに大きく、たとえば、RedisCluster のスロット範囲は 0 ~ 16383 です。スロットは、クラスター内のデータ管理と移行の基本単位です。広範囲スロットを使用する主な目的は、データ分割とクラスタ拡張を容易にすることです。各ノードは特定の数のスロットを担当します。

たとえば、クラスターに 3 つのノードがある場合、各ノードは平均して約 5460 スロットを担当します。高品質のハッシュ アルゴリズムを使用しているため、各スロットにマッピングされるデータは通常比較的均等であり、データはデータ パーティショニングのために 5 つのノードに均等に分割されます。Redis Cluster は仮想スロット パーティショニングを使用します。次に、Redis データ パーティショニング方法について説明します。

画像.png

スロットの範囲が 0 ~ 16383 であるのはなぜですか?

スロットの範囲が 0 ~ 16383 であり、これはスロット数が 16384 であることを意味するのはなぜですか? redis の作者は github に答えを持っています:なぜ redis-cluster は 16384 スロットを使用するのですか? · Issue #2576 · redis/redis · GitHub

画像.png

これはつまり:

Redis クラスターでは、ハンドシェイクが成功した後、データ情報を交換するためにノード間で定期的に ping/pong メッセージが送信されます。クラスター内のノードが増えるほど、メッセージ本文の内容も大きくなります。たとえば、10 ノードのステータス情報約 1kb 同時に、redis クラスター内のノードは ping メッセージを毎秒送信しています。たとえば、ノードの合計数が 200 の Redis クラスターでは、ping/pong メッセージが占有する帯域幅はデフォルトで 25M に達します。

したがって、スロットが 65536 の場合、ハートビート情報を送信するためのメッセージ ヘッダーは 8K に達し、送信されるハートビート パケットが大きすぎるため、帯域幅が無駄になります。

次に、redis クラスターのマスター ノードの数が 1,000 を超えることは基本的に不可能です。クラスター ノードの数が多いほど、ハートビート パケットのメッセージ本文で伝送されるデータも多くなります。ノード数が 1,000 を超える場合も、ネットワークの混雑が発生します。したがって、redis 作成者は、redis クラスター ノードの数が 1,000 を超えることを推奨しません。

したがって、ノード数が 1,000 未満の Redis クラスターの場合、各マスターに十分なスロットを確保するには 16,384 スロットで十分であり、65,536 に拡張する必要はありません。

さらに、Redis マスターノードの構成情報には、担当するハッシュスロットがビットマップの形式で保存され、送信プロセス中にビットマップは圧縮されますが、ビットマップスロットの充填率 / Nが大きい (N はノード数を表します)。つまり、ノード数が少なく、ハッシュ スロットの数が多い場合、ビットマップの圧縮率は非常に低くなり、リソースが無駄になります。

したがって、Redis の作成者は、より良い設計上のトレードオフとして 16384 スロットを採用することにしました。

Redis データ パーティション

Redis Cluser は仮想スロット パーティショニングを使用し、すべてのキーはハッシュ関数に従って 0 ~ 16383 の整数スロットにマッピングされます。計算式は次のとおりです: スロット=CRC16(キー) &16383。各ノードは、スロットの一部と、スロットによってマップされたキー値データを維持する責任を負います。

画像.png

画像.png

Redis仮想スロットパーティションの特徴

1. データとノードの関係を分離し、ノードの拡張と縮小の困難を簡素化します。

2. ノード自体はスロットのマッピング関係を維持するため、クライアントまたはプロキシ サービスがスロット パーティションのメタデータを維持する必要はありません。このインターフェイスは、ノード、スロット、キー間のマッピング クエリをサポートし、データ ルーティングやオンライン スケーリングなどのシナリオで使用されます。

3. データ パーティショニングは分散ストレージの中核であり、データ パーティショニング ルールを理解し、柔軟に使用することは、Redis Cluster をマスターするのに非常に役立ちます。

クラスター機能の制限事項

Redis クラスターには単一マシンと比較していくつかの機能制限があるため、開発者は事前に理解し、使用時に制限を回避する必要があります。制限事項は次のとおりです。

1. 主要なバッチ操作のサポートは制限されています。たとえば、mset と mget は現在、同じスロット値を持つキーに対するバッチ操作のみをサポートしています。mget や mget などの操作が複数のノードに存在する可能性があるため、異なるスロット値にマップされたキーはサポートされません。

2. キー トランザクション操作のサポートは制限されています。同様に、同一ノード上のマルチキートランザクション操作のみサポートされており、複数のキーが異なるノードに分散している場合、トランザクション機能は使用できません。

3. キーはデータ分割の最小粒度であるため、ハッシュ、リストなどの大きなキーと値のオブジェクトを異なるノードにマッピングすることはできません。

4. 複数のデータベーススペースはサポートされていません。スタンドアロン モードの Redis は 16 のデータベースをサポートできますが、クラスター モードでは 1 つのデータベース スペース (db 0) のみを使用できます。

5. レプリケーション構造は 1 つのレイヤーのみをサポートし、スレーブ ノードはマスター ノードのみをレプリケートでき、ネストされたツリー レプリケーション構造はサポートされません。

クラスターを構築する

Redis クラスターのパーティション分割ルールを導入したら、Redis クラスターの構築を開始しましょう。クラスターを構築するにはいくつかの方法があります。

1) Redis プロトコルに従って手動でビルドし、cluster meets、cluster addlots、cluster replicate コマンドを使用します。

2) 5.0以前では、ruby言語で書かれたredis-trib.rbが使用されており、使用前にruby言語環境をインストールする必要がありました。

3) Redis 5.0 以降では、redis-trib.rb が廃止され、クラスター構築機能が redis-cli に統合されました。

シンプルにして 3 番目の方法を使用して構築しましょう。クラスター内のノードの数は奇数以上である必要があります。つまり、少なくとも 3 つのノードが必要です。公式の推奨構成はマスター 3 つ、スレーブ 3 つです。マスター 3 つ、スレーブ 3 つでクラスターを構築しましょう。

ノード構成

ここでは、マスター ノードのポートが 6900、6901、および 6902 であり、スレーブ ノードのポートが 6930、6931、および 6932 であると規定します。

まず、ノードの conf ファイルを設定する必要があります。これは比較的統一されています。すべてのノードの設定ファイルは似ています。例としてポート 6900 を持つノードを考えてみましょう:

--javascripttypescriptbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

port 6900

# 这个部分是为了在一台服务上启动多台Redis服务,相关的资源要改
pidfile /var/run/redis_6900.pid
logfile "/home/lijin/redis/redis/log/6900.log"
dir "/hom

おすすめ

転載: blog.csdn.net/weixin_38996079/article/details/134725533