4 つの Redis クラスター スキームの紹介 + 利点と欠点の比較

サービス開発では、単一のマシンに単一障害点の問題が発生します。つまり、サービスがサーバー上にデプロイされ、サーバーがダウンするとサービスが利用できなくなります。サービスの可用性が高く、分散サービスが出現し、同じサービスが展開されます。複数のマシン上で、複数のサーバーがダウンしても、1 台のサーバーが利用可能であれば、サービスは利用できます。

Redisも同様で、スタンドアロン障害を解決するためにマスタースレーブモードが導入されていますが、マスタースレーブモードではマスターノード障害発生後、手動でサービスを切り替える必要があるという問題があります。サービスが復元される前に、スレーブ ノードからマスター ノードに転送されます。この問題を解決するために、redis は Sentinel モードを導入し、マスター ノードに障害が発生した後にスレーブ ノードを自動的にマスター ノードに昇格させ、手動介入なしでサービスを復元できます。

しかし、マスタースレーブモードでもセンチネルモードでもリアルデータシャーディングストレージは実現しておらず、各redisインスタンスが全量のデータを格納するため、リアルデータシャーディングストレージを実現するredisクラスターが誕生しました。ただし、redis クラスターのリリースが比較的遅かったため (正式バージョンは 2015 年にリリースされました)、大手メーカーは待ちきれず、Twemproxy、Codis などの独自の Redis データ断片化クラスター モデルを次々と開発しました。

マスタースレーブモード

Redis 単一ノードは、RDB および AOF 永続化メカニズムを通じてデータをハードディスクに永続化できますが、データはサーバーに保存され、サーバーにハードディスク障害などの問題が発生した場合、データは利用できなくなり、読み取ることができなくなります。分離、読み取り、書き込みがすべて同じサーバー上で行われるため、リクエスト量が多い場合には I/O ボトルネックが発生します。

単一障害点や読み取りと書き込みの非分離を回避するために、Redis はマスター データベースのデータが更新された後、更新されたデータが他のスレーブ データベースに自動的に同期されることを実現するレプリケーション機能を提供します。

上記の redis のマスター/スレーブ構造の特徴: マスターは複数のスレーブ ノードを持つことができ、スレーブ ノードはスレーブ ノードを持つことができ、スレーブ ノードはカスケード構造になります。

マスタースレーブモードのメリットとデメリット

  • 利点: マスター/スレーブ構造には、読み取りと書き込みの分離、効率の向上、データのバックアップ、および複数のコピーという利点があります。

  • 短所: 最大の短所は、マスター/スレーブ モードには自動フォールト トレランスおよび回復機能がないことです。マスター ノードに障害が発生すると、クラスターは動作できなくなり、可用性が比較的低くなります。スレーブ ノードを次の状態にアップグレードするには手動介入が必要です。マスターノード。

通常のマスター/スレーブ モードでは、マスター データベースがクラッシュした場合、スレーブ データベースを手動で切り替えてマスター データベースにする必要があります。

  • スレーブ データベースで SLAVE NO ONE コマンドを使用して、スレーブ データベースをマスター データに昇格させ、サービスを継続します。

  • 以前にクラッシュしたマスター データベースを起動し、SLAVEOF コマンドを使用してそれを新しいマスター データベースのスレーブ データベースとして設定し、データを同期します。

センチネルモード

1 つ目のタイプのマスター/スレーブ同期/レプリケーション モードでは、マスター サーバーがダウンした場合、スレーブ サーバーをマスター サーバーに手動で切り替える必要があります。これには手動による介入が必要で、手間がかかり、サービスが停止します。そこでセントリーモードの出番です。

Sentinel モードは Redis バージョン 2.6 から提供されましたが、当時このバージョンのモードは不安定であり、Redis バージョン 2.8 までセンチネル モードは安定しませんでした。

センチネル モードの中核は依然としてマスター/スレーブ レプリケーションですが、マスター/スレーブ モードと比較すると、マスター ノードがダウンして書き込みできない場合、追加の選出メカニズムがあります。つまり、新しいマスター ノードがすべてのスレーブ ノードから選出されます。 。選出メカニズムの実装は、システム内のセンチネル プロセスの開始に依存します。

上図に示すように、Sentry 自体に単一障害点の問題があるため、1 つのマスターと複数のスレーブを持つ Redis システムでは、複数の Sentinel を監視に使用できます。Sentinel はマスター データベースとスレーブ データベースを監視するだけでなく、お互いも監視し合う。各センチネルは独立したプロセスであり、プロセスとしては独立して実行されます。

(1) センチネルモードの役割:

すべてのサーバーが正常に実行されているかどうかを監視します。監視サーバーの実行ステータスを返すコマンドを送信し、マスター サーバー、スレーブ サーバー、センチネルを処理および監視し、相互監視も行います。

フェイルオーバー: センチネルはマスターがダウンしていることを検出すると、自動的にスレーブをマスターに切り替え、パブリッシュ/サブスクライブ モードを通じて他のスレーブ サーバーに通知し、設定ファイルを変更してマスターに切り替えます。同時に、問題のある古いマスターも新しいマスターのスレーブになります。つまり、古いマスターが復元されたとしても、元のマスターの状態には戻りませんが、新しいマスターのスレーブになります。 。

(2) センチネルの実施原則

Sentinel はプロセスを開始すると、構成ファイルの内容を読み取り、次の構成を通じて監視対象のメイン データベースを見つけます。

sentinel monitor master-name ip port quorum
#master-name是主数据库的名字
#ip和port 是当前主数据库地址和端口号
#quorum表示在执行故障切换操作前,需要多少哨兵节点同意。

ここでマスターノードのみ接続する必要があるのは、マスターノードのinfoコマンドを使用してスレーブノードの情報を取得することでスレーブノードとの接続を確立し、同時に新たなノードの情報を知ることができるためです。マスターノードの情報情報を通じてスレーブノードを追加しました。

センチネル ノードは複数のマスター ノードを監視できますが、センチネル ノードがクラッシュすると複数のクラスターのスイッチオーバーが同時に失敗するため、これはお勧めできません。Sentinel が起動すると、メイン データベースに対して 2 つの接続が確立されます。

  • メイン データベース _sentinel_:hello チャネルをサブスクライブして、データベースも監視するセンチネル ノードに関する情報を取得します。

  • 定期的に info コマンドを master データベースに送信して、master データベース自体に関する情報を取得します。

メイン データベースとの接続を確立した後、次の 3 つの操作が定期的に実行されます。

  • (1) 10 秒ごとに情報コマンドをマスターとスレーブに送信します。現在のデータベース情報を取得する機能で、例えば新たなスレーブノードが見つかった場合には接続を確立して監視リストに追加し、マスタ・スレーブデータベースの役割が変更された場合には情報を更新します。

  • (2) マスターデータとスレーブデータベースの _sentinel_:hello チャネルに 2 秒ごとに独自の情報を送信します。役割は、独自の監視データを Sentry と共有することです。各センチネルはデータベースの _sentinel:hello チャネルにサブスクライブします。他のセンチネルがメッセージを受信すると、そのセンチネルが新しいセンチネルかどうかを判断します。そうであれば、センチネル リストに追加して接続を確立します。

  • (3) すべてのマスター/スレーブ ノードおよびすべてのセンチネル ノードに 1 秒ごとに ping コマンドを送信し、ノードが生存しているかどうかを監視します。

(3) 主観的オフラインと客観的オフライン

センチネル ノードが ping コマンドを送信したときに、ノードが一定時間 (ミリ秒後のダウン) 経過しても応答しない場合、センチネルは主観的にオフラインであるとみなします。主観的オフラインとは、現在の Sentinel がノードがオフラインになったと信じていることを意味します。ノードがマスター データベースの場合、Sentinel はフェイルオーバーが必要かどうかをさらに判断します。このとき、コマンド (SENTINEL is-master-) を送信します。 down-by-addr ) を使用して、マスター ノードが主観的にオフラインであると他のセンチネル ノードに判断するかどうかを尋ねます。指定された数 (クォーラム) に達すると、センチネルは客観的にマスター ノードがオフラインであると判断します。

マスター ノードが客観的にオフラインになった場合、マスター/スレーブ切り替えが必要になります。マスター/スレーブ切り替えの手順は次のとおりです。

  • 先頭のセンチネルを選出します。

  • リーダーセンチネルのすべてのスレーブは、最高の優先順位でスレーブ データベースを選択します。優先順位は、スレーブ優先順位オプションを介して設定できます。

  • 優先順位が同じ場合、データベースからコピーされるコマンドのオフセットが大きいほど (つまり、より多くのデータがコピーおよび同期され、データが新しいほど)、優先順位も高くなります。

  • 上記の条件が同じ場合は、実行IDの小さいスレーブデータベースを選択してください。

スレーブ データベースが選択されると、センチネルはスレーブ no one コマンドを送信してマスター データベースにアップグレードし、slaveof コマンドを送信して他のスレーブ ノードのマスター データベースを新しいマスター データベースとして設定します。

(4) センチネルモードのメリット・デメリット

1. 利点

  • センチネル モードはマスター スレーブ モードに基づいており、マスター スレーブ モードでマスター障害が発生した場合に自動的に障害を切り替えることができないという問題を解決します。

2. 不足 - 問題

  • これは集中型のクラスター実装スキームです。書き込みリクエストを受信して​​処理する Redis ホストは常に 1 つだけであり、書き込み操作は単一マシンのボトルネックの影響を受けます。

  • クラスター内のすべてのノードは全量のデータを保存しますが、これはメモリースペースを無駄にし、真の分散ストレージを実現しません。データの量が大きすぎる場合、マスターとスレーブの同期はマスターのパフォーマンスに重大な影響を与えます。

  • Redis ホストがダウンした後は、投票が終了するまでホストとスレーブが誰であるか誰も分からないため、センチネル モードは投票の場合には機能しません。このとき、Redis は書き込み操作を禁止する保護メカニズムも開きます。新しい Redis ホストが選挙されるまで。

マスタースレーブモードやセンチネルモードで各ノードに保存されるデータは全量のデータですが、データ量が多すぎる場合には保存データを分割して複数のredisインスタンスに保存する必要があります。現時点では、Redis Sharding テクノロジーが使用されます。

大手メーカーのRedisクラスタソリューション

Redis は、バージョン 3.0 より前のシングル インスタンス モードのみをサポートしています。Redis 開発者 Antirez 氏は、自身のブログで早くも Redis バージョン 3.0 にクラスター機能を追加することを提案していましたが、バージョン 3.0 は 2015 年まで正式バージョンをリリースしていませんでした。大手企業はそれを待ちきれず、バージョン 3.0 のリリース前に、Redis のストレージ ボトルネックを解決するために、独自の Redis クラスター ソリューションを次々と立ち上げました。これらのソリューションの中心的なアイデアは、データのシャーディング (シャーディング) を複数の Redis インスタンスに保存することであり、各シャードは Redis インスタンスです。

(1) クライアントの断片化

クライアント側のシャーディングは、Redis クライアントの事前定義されたルーティング ルール (一貫性のあるハッシュを使用) を通じて、Redis クライアントにシャーディングのロジックを配置することによって実装されます (例: jedis はすでに Redis シャーディング機能、つまり ShardedJedis をサポートしています)。 、キーへのアクセスは別の Redis インスタンスに転送され、データのクエリ時に返された結果が収集されます。このシナリオのスキーマを図に示します。

クライアント側シャーディングの長所と短所:

利点: シャーディングにハッシュ コンセンサス アルゴリズムを使用するクライアント側シャーディング テクノロジの利点は、すべてのロジックが制御可能であり、サードパーティの分散ミドルウェアに依存しないことです。サーバー側の Redis インスタンスは互いに独立しており、関連性がありません。各 Redis インスタンスは 1 つのサーバーのように動作し、直線的に拡張することが非常に簡単で、システムは非常に柔軟です。開発者はシャーディングとルーティングのルールを実装する方法を知っているため、穴を踏むことを心配する必要はありません。

1. 一貫したハッシュ アルゴリズム:

これは分散システムで一般的に使用されるアルゴリズムです。たとえば、分散ストレージ システムは特定のノードにデータを保存する必要があります。mod(key,d) などの共通のハッシュ方式を使用してデータを特定のノードにマップする場合、key はデータのキーです。 d マシン ノードの数です。マシンがクラスタに参加またはクラスタから離脱すると、すべてのデータ マッピングが無効になります。

一貫性のあるハッシュ アルゴリズムは、通常の剰余ハッシュ アルゴリズムの拡張性の低さの問題を解決し、サーバーがオンラインまたはオフラインのときに、できるだけ多くのリクエストが元のルーティングされたサーバーにヒットすることを保証できます。

2. 実装方法: MURMUR_HASH ハッシュ アルゴリズム、ketamahash アルゴリズムなどの一貫したハッシュ アルゴリズム

たとえば、Jedis の Redis Sharding 実装では、一貫性のあるハッシュ アルゴリズム (一貫性のあるハッシュ) を使用して、キーとノード名を同時にハッシュし、マッピングの一致を実行します。使用されるアルゴリズムは MURMUR_HASH です。

単純なハッシュのようなモジュロ マッピングではなく一貫したハッシュを使用する主な理由は、ノードが追加または削除されるときに、再マッチングによる再ハッシュが発生しないことです。一貫性のあるハッシュは隣接ノードのキー配布にのみ影響し、影響は小さいです。

不十分:

  • これは静的シャーディング スキームであり、Redis インスタンスの数を増減し、シャーディング プログラムを手動で調整する必要があります。

  • 運用保守コストが比較的高く、クラスタデータに問題が発生した場合は運用保守担当者と開発者の協力が必要となるため、問題解決のスピードが遅くなり、部門間のコミュニケーションコストも増加します。

  • 異なるクライアント プログラムで、同じルート シャーディング ロジックを維持するコストは膨大です。たとえば、Java プロジェクトと PHP プロジェクトは Redis クラスターのセットを共有しており、ルーティング断片化ロジックは同じロジックを 2 セット記述する必要があり、将来的には 2 セットのメンテナンスが必要になります。

クライアント シャーディングに関する最大の問題の 1 つは、サーバー側 Redis インスタンス グループのトポロジ構造が変更されると、各クライアントを更新して調整する必要があることです。クライアント シャーディング モジュールを個別に取り出して別のモジュール (ミドルウェア) を形成できれば、クライアントとサーバー間の橋渡しとしてこの問題を解決でき、このときにプロキシ シャーディングが登場します。

(2) プロキシのフラグメンテーション

Twemproxy は最も広く使用されている Redis エージェントのフラグメンテーションであり、Twitter によるオープンソース Redis エージェントです。その基本原理は次のとおりです: ミドルウェアの形式を通じて、Redis クライアントはリクエストを Twemproxy に送信し、Twemproxy はそれを正しい Redis インスタンスに送信します最後に、Twemproxy は結果を集約してクライアントに返します。

Twemproxy は、複数の Redis インスタンスを統合的に管理するプロキシ層を導入することで、Redis クライアントは Twemproxy 上で動作するだけでよく、背後にある Redis インスタンスの数を気にする必要がなく、Redis クラスターを実現します。

Twemproxy の利点:

  • クライアントは、コード ロジックを変更せずに、Redis インスタンスと同様に Twemproxy に接続します。

  • 無効な Redis インスタンスの自動削除がサポートされています。

  • Twemproxy は Redis インスタンスとの接続を維持し、クライアントと Redis インスタンス間の接続の数を減らします。

Twemproxy の欠点:

  • Redis クライアントからの各リクエストは Twemproxy プロキシを経由して Redis サーバーに到達するため、このプロセスでパフォーマンスが低下します。

  • 使いやすい監視および管理のバックグラウンド インターフェイスがないため、運用および保守の監視には役立ちません。

  • Twemproxy の最大の問題点は、スムーズに拡張/縮小できないことです。運用保守担当者にとって、ビジネスニーズにより Redis インスタンスを追加する際の作業負荷は非常に大きくなります。

Twemproxy は、最も広く使用され、実績があり、安定した Redis プロキシとして、業界で広く使用されています。

(3) コード

TwemproxyではRedisインスタンスをスムーズに増やすことができないという問題が大きな不便をもたらしていたため、PeapodではGo言語とC言語をベースにRedisインスタンスのスムーズな増加を支援するRedisプロキシソフトウェア「Codis」を独自に開発し、2014年11月に提供を開始しました。 GitHub 上のソース。

Codis のアーキテクチャ図では、Codis はマスター CodisRedis と 1 つ以上のスレーブ CodisRedis を指定することで Redis クラスターの高可用性を実現する Redis Server Group を導入しています。プライマリ CodisRedis がハングアップすると、Codis はセカンダリ CodisRedis をプライマリ CodisRedis に自動的に昇格させません。これにはデータの一貫性の問題が伴います (Redis 独自のデータ同期ではマスター/スレーブの非同期レプリケーションが使用され、データがプライマリ CodisRedis に正常に書き込まれた場合、スレーブ CodisRedis がこのデータを読み取ったかどうかを保証するため)、管理者は管理インターフェイスでスレーブ CodisRedis をマスター CodisRedis に手動で昇格させる必要があります。

手動処理​​が面倒な場合には、エンドウ豆ポッドには、マスター CodisRedis がダウンしていることを検出したときにオフラインにしてスレーブ CodisRedis をマスター CodisRedis に昇格させるツール Codis-ha も提供されています。

CodisはPre-shardingの形式を採用しており、起動時に1024個のスロットが作成され、1スロットが1ボックスに相当し、各ボックスは1から1024までの固定番号を持ちます。スロット ボックスは Key を格納するために使用されます。Key がどのボックスに格納されるかについては、「crc32(key)%1024」というアルゴリズムによって数値が取得されます。この数値の範囲は 1 ~ 1024 でなければなりません。キーは対応する番号スロットに配置されます。

たとえば、アルゴリズム「crc32(key)%1024」を通じてキーによって取得された数値が 5 の場合、それを 5 とコード化されたスロット (ボックス) に置きます。1 つのスロットに配置できる Redis サーバー グループは 1 つだけであり、1 つのスロットを複数の Redis サーバー グループに配置することはできません。Redis サーバー グループは、少なくとも 1 スロット、最大 1024 スロットを保存できます。したがって、Codis では最大 1024 の Redis サーバー グループを指定できます。

Codis の最大の利点は、Redis サーバー グループ (Redis インスタンス) のスムーズな増加 (減少) をサポートし、安全かつ透過的にデータを移行できることであり、この点が Twemproxy などの静的分散 Redis ソリューションと異なる点でもあります。Codis が Redis サーバー グループを追加した後、スロットの移行が必要になりました。

たとえば、システムには 2 つの Redis サーバー グループがあり、Redis サーバー グループとスロットの対応は次のようになります。

Redis サーバー グループが追加されると、スロットが再割り当てされます。Codis がスロットを割り当てる方法は 2 つあります。

1 つ目の方法: Codis 管理ツール Codisconfig を使用して手動で再配布し、各 Redis サーバー グループに対応するスロットの範囲を指定します。たとえば、次のように Redis サーバー グループとスロットの新しい対応関係を指定できます。

2 番目の方法: Codis 管理ツール Codisconfig のリバランス機能を通じて、各 Redis サーバー グループのメモリに応じてスロットが自動的に移行され、データ バランスが実現されます。

Redis クラスター

Redis のセンチネル モードは高可用性と読み取り/書き込み分離を実現できますが、いくつかの欠点があります。

  • Sentinel モードでは、各 Redis サーバーが同じデータを保存するため、メモリ領域が無駄になり、データ量が多すぎて、マスターとスレーブの同期がマスターのパフォーマンスに重大な影響を与えます。

  • Sentinel モードは集中クラスタ実装スキームであり、各スレーブ マシンはホスト マシンと高度に結合されており、マスターのダウンタイムからスレーブ選択マスターの回復までの期間はサービスが利用できなくなります。

  • Sentinel モードでは、書き込みリクエストを受信して​​処理する Redis ホストは常に 1 つだけですが、書き込み操作は依然として単一マシンのボトルネックの影響を受けており、真の分散アーキテクチャは実装されていません。

Redis は、Redis の分散ストレージ、つまり、各 Redis ノードに異なるデータが保存されることを実現するために、3.0 で Cluster クラスター モードを追加しました。単一マシンの Redis 容量が限られているという問題を解決するために、クラスター モードでは、特定のルールに従ってデータを複数のマシンに分散します。メモリ/QPS は単一マシンに限定されず、分散クラスターの高い拡張性の恩恵を受けることができます。 。

Redis Cluster は、複数のマスターと複数のスレーブを使用するサーバー シャーディング テクノロジー (シャーディングとルーティングはサーバー側で実装されます) であり、各パーティションは Redis ホストと複数のスレーブで構成されます。Redis Cluster クラスターは P2P モデルを採用しており、完全に分散化されています。

上の図に示すように、クラスターの展開には少なくとも 3 つのマスター ノードが必要であることが公式に推奨されており、6 つのノードで 3 つのマスターと 3 つのスレーブのモードを使用するのが最適です。Redis Cluster クラスターには次の特徴があります。

  • クラスターは完全に分散化されており、複数のマスターと複数のスレーブを採用しており、すべての Redis ノードは相互接続され (PING-PONG メカニズム)、バイナリ プロトコルが内部で使用されて伝送速度と帯域幅が最適化されます。

  • クライアントは、中間プロキシ層を介さずに Redis ノードに直接接続されます。クライアントはクラスター内のすべてのノードに接続する必要はありませんが、クラスター内の使用可能な任意のノードに接続できます。

  • 各パーティションは Redis ホストと複数のスレーブで構成され、シャードとシャードは相互に並列されます。

  • 各マスター ノードは、スロットの一部と、スロットにマッピングされたキーと値のデータを維持する責任を負います。クラスター内の各ノードは、完全な量のスロット情報を持ち、スロットを通じて、各ノードは特定のデータがどのノードであるかを認識します。に保存されています。

Redis クラスターは主に大規模データ + 高同時実行 + 高可用性のシナリオに適しています。大規模なデータがある場合は Redis クラスターを使用することをお勧めします。データの量がそれほど多くない場合は、sentinel を使用するだけで十分です。Redis クラスターのパフォーマンスと高可用性は、センチネル モードよりも優れています。

Redis Cluster は一貫したハッシュ アルゴリズムの代わりに仮想ハッシュ スロット パーティショニングを採用し、いくつかのカード スロットを事前に割り当てます。すべてのキーはハッシュ関数に従ってこれらのスロットにマッピングされます。各パーティションのマスター ノードはスロットの一部を維持する責任を負い、マップされたスロット、キーと値のデータ。

おすすめ

転載: blog.csdn.net/2301_77463738/article/details/131263827