メモリベースの Redis は、さまざまな Web 開発ビジネスで最も一般的に使用されるキーと値のデータベースです。私たちのビジネスでは、ユーザーのログイン ステータス (セッション ストレージ) を保存し、一部のホット データのクエリを高速化するためによく使用されます。 mysql 速度の点では、単純なメッセージ キュー (LPUSH および BRPOP)、サブスクリプション パブリッシング (PUB/SUB) システムなどの作成により、速度が桁違いに向上しました。大手インターネット企業は通常、さまざまなビジネス コールに基本サービスとして Redis ストレージを提供する専門チームを抱えています。
ただし、基本的なサービスのプロバイダーは、発信者から「サービスの可用性は高いですか?」と尋ねられます。貴社のサービスで頻繁に問題が発生して、私のビジネスに支障をきたさないことが最善です。最近、自分のプロジェクトで小さな「高可用性」Redis サービスも構築しました。これが私の要約と考察です。
まず第一に、Redis サービスの高可用性を構成するもの、つまり、さまざまな異常な状況下でもサービスを正常に提供できるものを定義する必要があります。あるいは、異常が発生した場合でも、短時間で通常のサービスを回復できます。いわゆる例外には、少なくとも次の可能性が含まれている必要があります:
[例外 1] 特定のノード サーバーのプロセスが突然ダウンした (たとえば、開発者が無効になり、サーバーの redis-server プロセスを強制終了した)
【例外2】特定のノードサーバーがダウンしています。これは、このノード上のすべてのプロセスが停止していることに相当します(たとえば、運用保守の障害によりサーバーの電源が切断されます。たとえば、一部の古いマシンにハードウェア障害があるなど)
【異常3】任意の2つのノードサーバー間の通信が遮断される(例:手の不自由な派遣社員が2つのコンピュータ室間の通信に使用する光ケーブルを掘り出すなど)
実際、上記の例外はどれも軽微なものです。高可用性を実現するための基本的な指針は、複数の低確率イベントが同時に発生する確率は無視できるということです。短期間の単一障害点を許容するようにシステムを設計する限り、高可用性を実現できます。
Keepalived、Codis、Twemproxy、Redis Sentinel など、高可用性 Redis サービスを構築するためのソリューションがインターネット上に多数あります。このうち、Codis と Twemproxy は主に大規模な Redis クラスターで使用されており、Redis が Redis Sentinel を正式にリリースする前は twitter と Wandoujia によって提供されていたオープンソース ソリューションでもありました。私のビジネスのデータ量はそれほど多くないため、クラスター サービスを提供するとマシンの無駄になります。最終的に、Keepalived と Redis Sentinel のどちらかを選択し、公式ソリューションである Redis Sentinel を選択しました。
Redis Sentinel は、Redis Server サービスが正常かどうかを監視するプロセスとして理解でき、異常が検出されると、バックアップ (スレーブ) Redis Server が自動的に有効になり、外部ユーザーがサービス内の異常に気づかないようにすることができます。 Redis サービス。単純な手順から複雑な手順に従って、最小限で可用性の高い Redis サービスを構築します。
オプション 1: Sentinel なしの Redis Server のスタンドアロン バージョン
通常、個人の Web サイトを構築するとき、または日常の開発を行うときは、Redis Server の単一インスタンスをセットアップします。呼び出し元は Redis サービスに直接接続でき、クライアントと Redis 自体も同じサーバー上にあります。結局のところ、この組み合わせは個人的な学習と娯楽にのみ適しています。結局のところ、この構成には解決できない単一障害点が常に存在します。 Redis サービス プロセスがハングするか、サーバー 1 がシャットダウンされると、サービスは利用できなくなります。また、Redis データの永続性が構成されていない場合、Redis に既に保存されているデータも失われます。
オプション 2: マスター/スレーブ同期 Redis サーバー、単一インスタンス Sentinel
高可用性を実現し、解決策 1 で説明した単一障害点の問題を解決するには、バックアップを追加する必要があります通常、マスターはサービスを提供し、スレーブは同期とバックアップのみを担当します。同時に、追加の Sentinel プロセスが開始されて 2 つの Redis Server インスタンスの可用性を監視するため、マスターがハングアップしたときにスレーブがマスターの役割に昇格し、サービスの提供を継続できるようになります。これにより、高可用性が実現されます。 Redisサーバーの。これは高可用性サービス設計の基礎に基づいています。つまり、単一点障害自体は確率の低いイベントであり、同時に複数の単一点障害が発生します (つまり、マスターとスレーブが同時にハングアップします)。時間)は(基本的に)不可能な出来事と考えることができます。
Redis サービスの呼び出し元の場合、今接続する必要があるのは Redis Server ではなく Redis Sentinel サービスです。一般的な呼び出しプロセスは、クライアントが最初に Redis Sentinel に接続し、現在の Redis サーバーのどのサービスがマスターでどのサービスがスレーブであるかを尋ね、その後、対応する Redis サーバーに接続して操作します。もちろん、現在のサードパーティ ライブラリは一般的にこの呼び出しプロセスを実装しており、手動で実装する必要はなくなりました (Nodejs の ioredis、PHP の predis、Golang の go-redis/redis、JAVA の jedis など)。
しかし、Redis Server サービスのマスター/スレーブ切り替えを実装した後、新しい問題が発生しました。つまり、Redis Sentinel 自体もシングル ポイント サービスであり、Sentinel プロセスがハングすると、クライアントはサービスを利用できなくなります。センチネルに接続します。したがって、オプション 2 の構成では高可用性を実現できません。
オプション 3: マスター/スレーブ同期 Redis サーバー、デュアル インスタンス Sentinel
解決策 2 の問題を解決するために、追加の Redis Sentinel プロセスと 2 つの Sentinel プロセスも開始します。同時に顧客にサービスを提供する 端末はサービス発見機能を提供します。クライアントの場合、任意の Redis Sentinel サービスに接続して、現在の Redis Server インスタンスに関する基本情報を取得できます。通常、クライアント側で複数の Redis Sentinel リンク アドレスを設定します。クライアントは、特定のアドレスに接続できないことを検出すると、他の Sentinel インスタンスに接続しようとします。もちろん、これを手動で実装する必要はありません。さまざまな開発言語 より一般的な Redis 接続ライブラリが、この機能の実現に役立ちました。私たちの期待は、Redis Sentinel の 1 つが電話を切ったとしても、サービスを提供できる別の Sentinel が存在することです。
しかし、ビジョンは美しいですが、現実は残酷です。このようなアーキテクチャでは、Redis サービスの高可用性を実現することは依然として不可能です。オプション 3 の概略図では、赤い線が 2 つのサーバー間の通信であり、私たちが想定した異常シナリオ ([異常 2]) は、特定のサーバーが全体としてダウンしていると想定した方がよいでしょう。現時点では、サーバー 2 では Redis Sentinel とスレーブ Redis Server のみがダウンしています。現時点では、Sentinel はサービスを継続するために実際に残りのスレーブをマスターに切り替えることはありません。これにより、Redis サービスが利用できなくなります。これは、Redis の設定では、Sentinel プロセスの 50% 以上が接続および接続できる場合のみであるためです。新しいマスターに投票すると、マスターとスレーブの切り替えが実際に行われます。この例では、2 つの Sentinel のうち 1 つだけを接続できます。これは 50% に相当し、マスター/スレーブの切り替えが可能なシナリオではありません。
なぜ Redis にはこの 50% 設定があるのかと疑問に思われるかもしれません。 Sentinel 接続の 50% 以下を許可すると仮定すると、マスター/スレーブ切り替えも実行できます。 [例外 3] を想像してください。つまり、サーバー 1 とサーバー 2 の間のネットワークは中断されていますが、サーバー自体は動作しています。以下の図に示すように:
実際、サーバー 2 の場合、サーバー 1 が直接ダウンすると、サーバー 1 がネットワークに接続できなくなったのと同じ効果が生じます。コミュニケーションが可能になります。ネットワークが中断されたときに、サーバー 2 の Sentinel がスレーブからマスターに切り替わることを許可すると、その結果、外部サービスを提供できる 2 つの Redis サーバーが存在することになります。クライアントによって実行される追加、削除、および変更操作は、(クライアントが接続している Sentinel に応じて) サーバー 1 の Redis またはサーバー 2 の Redis に影響を与える可能性があり、データの混乱を引き起こす可能性があります。たとえ後でサーバー 1 とサーバー 2 の間のネットワークが復旧したとしても、データを統合することはできず (2 つの異なるデータ、誰を信頼すればよいでしょうか?)、データの整合性は完全に破壊されます。
オプション 4: マスター/スレーブ同期 Redis サーバー、Sentinel の 3 つのインスタンス
オプション 3 では高可用性を実現できないため、上の図に示すように、最終バージョンはオプション 4 です。実際、これが私たちが最終的に構築したアーキテクチャです。サーバー 3 を導入し、3 上に Redis Sentinel プロセスを構築しました。現在、3 つの Sentinel プロセスが 2 つの Redis Server インスタンスを管理しています。このシナリオでは、単一プロセスの障害、単一マシンの障害、または 2 台のマシン間のネットワーク通信障害のいずれであっても、Redis サービスを外部に提供し続けることができます。
実際、マシンが比較的アイドル状態の場合は、もちろんサーバー 3 で Redis サーバーを開いて 1 マスター + 2 スレーブ アーキテクチャを形成することもでき、各データに 2 つのバックアップがあり、可用性が向上します。もちろん、スレーブの数は多いほど良いのですが、マスターとスレーブの同期にも時間がかかります。
シナリオ 4 では、サーバー 1 と他のサーバー間の通信が完全に中断されると、サーバー 2 と 3 はスレーブからマスターに切り替わります。クライアントの場合、現時点ではサービスを提供するマスターが 2 つあり、ネットワークが復旧すると、停止中にサーバー 1 に落ちた新しいデータはすべて失われます。この問題を部分的に解決したい場合は、Redis サーバー プロセスが自身のネットワークに問題を検出したときに、サービスを直ちに停止して、ネットワーク障害中に新しいデータが受信されるのを避けるように、Redis サーバー プロセスを構成できます (Redis の最小のセクションを参照してください)。 slaves-to-write と min-slaves-max-lag の 2 つの構成項目)。
この時点で、3 台のマシンを使用して高可用性 Redis サービスを構築しました。実際、インターネットには、サービス プロバイダーのマシンではなくクライアント マシンに Sentinel プロセスを配置する、よりマシンを節約する方法があります。ただ、社内では一般的なサービスの提供者と発信者が同じチームから所属しているわけではありません。 2 つのチームが同じマシンを一緒に操作する場合、通信の問題による誤操作が発生しやすいため、人的要因を考慮して、引き続きオプション 4 のアーキテクチャを採用しました。また、サーバー 3 では Sentinel プロセスが 1 つだけ実行されているため、サーバー リソースをあまり消費せず、他のサービスの実行にも使用できます。
使いやすさ: Redis Sentinel を Redis のスタンドアロン バージョンのように使用します
サービスプロバイダーとして、私たちは常にユーザーエクスペリエンスの問題について話しています。上記の解決策の中には、クライアントにとって使いにくいものは常にあります。 Redis のスタンドアロン バージョンの場合、クライアントは IP とポートを指定するだけで Redis サーバーに直接接続し、サービスを使用できます。 Sentinel モードに変換した後、クライアントは Sentinel モードをサポートするいくつかの外部依存パッケージを使用する必要があり、また独自の Redis 接続構成も変更する必要がありますが、これは明らかに「見栄っ張りな」ユーザーには受け入れられません。スタンドアロン版の Redis を使用する場合のように、クライアントに固定 IP とポートを与えるだけでサービスを提供する方法はありますか?
答えはもちろんイエスです。これには、上の図に示すように、仮想 IP (仮想 IP、VIP) の導入が必要になる場合があります。 Redis サーバーのマスターが配置されているサーバーを仮想 IP で指定できます。Redis のマスターとスレーブの切り替えが発生すると、コールバック スクリプトが VIP をスレーブが配置されているサーバーに切り替えます。このように、クライアントにとっては、高可用性 Redis サービスのスタンドアロン バージョンをまだ使用しているように見えます。
結論
スタンドアロンバージョンの Redis を実行するのと同じように、サービスを構築して「使用可能」にするのは実際には非常に簡単です。しかし、「高可用性」を実現しようとすると、事態は複雑になります。ビジネスでは、2 つの追加サーバー (3 つの Sentinel プロセス + 1 つのスレーブ プロセス) が使用されており、万が一の事故が発生した場合でもサービスを確実に利用できるようにします。実際のビジネスでは、プロセス監視のためにスーパーバイザも有効にします。プロセスが予期せず終了すると、プロセスは自動的に再起動を試みます。
関連する推奨事項:
linux インストール redis サービスと php redis 拡張機能
以上がRedisサービスアーキテクチャの分析と構築を包括的にマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。