ブログ

上位 5 つのスケーラビリティ パターン

ロリ・マクヴィッティ サムネイル
ロリ・マクヴィッティ
2018年5月30日公開

アプリケーションが通貨となる経済においては、可用性は重大な問題です。 応答しないアプリは即座に削除され、Yelp の否定的なレビューと同じ速さと皮肉をもってインターネット上で悪口を言われます。

インターネットの初期の頃から、組織はアプリケーション (昔は Web サイト) が 24 時間 365 日利用できるように努めてきました。 なぜなら、インターネットは決して眠らず、決して休暇を取らず、決して病欠をしないからです。

そのニーズ (実際には要件) を満たすために、スケーラビリティは可用性を提供する最初のアプリケーション サービスの 1 つとして登場しました。 可用性のニーズに応える最も目に見える、そして最もよく理解されているアプリケーション サービスは、負荷分散です。

ただし、負荷分散にはさまざまな形式があり、このコア テクノロジを使用して実装できるスケーラビリティ パターンも多数あります。 今日は、アプリとインターネットを 24 時間 365 日オンライン状態に保ち、利用できるようにするために使用されている上位 5 つのスケーラビリティ パターンについて説明します。

グローバル サーバー負荷分散 (GSLB)

GSLB はひどく誤った名前です。 それは実際にはサーバーの負荷分散に関するものではなく、サイトの可用性に関するものでした。 今日では、それはアプリの可用性も意味するように拡張されています。

GSLB は、1 つのデータ センター (クラウドまたは従来型) が応答しない場合に、別のデータ センターを見つけることができるようにする手段です。 GSLB はドメイン レベルまたはホスト レベルで適用できます。 したがって、api.example.com だけでなく、 example.com を場所間で切り替えるためにも使用できます

GSLB は、最も基本的な、初歩的な DNS ベースの負荷分散を使用します。 つまり、ドメインまたはホストに関連付けられた IP アドレスのリストがあり、最初の IP アドレスが利用できない場合は、リクエストはリストの 2 番目、または 3 番目、4 番目などに送信されます。

このプロセスには 2 つのステップがあります。

  1. グローバル ロード バランサーに適切な IP アドレスを問い合わせます。 これは GSLB に常に伴うマイナス面です。過去 15 分以内、または cheese.com の IP アドレスの現在の TTL が何であれ、問い合わせを行った場合、最後に受信した応答が返されます。 そのため、その時間内にサイトがダウンした場合、接続できなくなります。
  2. GSLB 照会によって返されたサイトの IP アドレスにリクエストを実行します。 これは多くの場合、独自のアルゴリズムと意思決定プロセスを使用して適切なリソースにリクエストを送信するローカルロード バランサになります。

通常、ステップ 1 で行われる決定にはインテリジェンスは含まれません。これは、特定のサイトが応答しているかどうかのみに基づいて行われます。 それでも、クラウド、ホスティング プロバイダー、オンプレミスなど、複数の場所を使用して可用性を確保することができます。 さまざまな地理的エリアから戦略的に場所を選択することで、自然災害やインターネットの停止の影響を回避できます。

しかし、それはむしろ DR (災害復旧) または BC (事業継続) のシナリオです。 地理位置情報やアプリケーション パフォーマンスなどのよりスマートな GSLB アプリケーション サービスを活用するものもあります。 したがって、サイト A のアプリのパフォーマンスが低い場合は、問題が解決するまで訪問者をサイト B に送信する必要があるかもしれません。 あるいは、パフォーマンスを向上させるために、ユーザーを地理的に最も近い場所に誘導したい場合もあります (光の速度は依然として原則であり、距離はアプリのパフォーマンスに重要であるため)。

決定がどのようになされるかに関係なく、基本的なパターンは同じです。 GLSB は、利用可能なサイトの 1 つの IP アドレスを返すことで、物理的に分離された複数のサイトにリクエストを分散します。 API であろうとアプリであろうと、GSLB はトップレベルの可用性保証パターンです。  

従来の負荷分散 (POLB)

接続ベースの可用性

Plain Old Load Balancing (POLB) は、標準的な TCP ベースの負荷分散を説明するために私がよく使用する用語です。 このパターンを使用すると、アプリを複製し、クライアント (ユーザー、デバイス) とアプリ間の接続を確立するだけで可用性が実現されます。

ロード バランサ (またはプロキシ) は接続要求を受信し、利用可能なアプリ インスタンスを選択し、接続を転送します。 これがロード バランサーがアクティブに関与する最後の時間です。 これは、2 人の同僚の会議を促進する「紹介メール」のようなものです。 最初のやり取りでは積極的に参加しますが、その後は CC ラインに移動され、通常はそれ以上関与しません。

リクエストをどのように送信するかの選択にはアルゴリズム以外の何も関与していないため、私は POLB という用語を使用しています。 残念ながら、リクエストを分散するために使用されるアルゴリズムによっては、問題が発生する可能性が多数あります。 たとえば、ラウンドロビンでは容量やパフォーマンスは考慮されません。 「次のアプリ」を選択するだけで、リクエストが実行されます。 「最小接続」を選択すると、リソースが読み込まれることでパフォーマンスにすぐに影響が出る可能性があります。一方、他のオプションの方が高速になる可能性があります。 アルゴリズムの選択は、可用性を維持する上で重要な要素になります。

POLB は、コンテナ環境内および多くのクラウドネイティブ負荷分散サービスにおける負荷分散のデフォルトの方法です。

持続性

スティッキーセッションと SSL

3 層アプリケーションの現実の 1 つは、原則として、ステートフルであることです。 つまり、アプリケーションの動作に重要な、リクエストとレスポンス間の情報を保存します。 ショッピング カート、認証情報、ステータス、最後にアクセスしたページ、プロセスのどのステップを実行しているかなど、さまざまな情報が「セッション」の一部として保存されることがよくあります。 問題は、3 層フレームワークを使用して開発された多くのアプリが、そのセッションをデータベースではなく、アプリケーションまたは Web サーバーに保存することになったことです。 つまり、一度サーバーに接続すると、すべての情報が利用可能であることを確認するために、そのサーバーに何度も戻る必要がありました。

ロード バランサはさまざまな方法で永続性を実装しましたが、最も一般的なのは Cookie ベースです。 セッション ID は Cookie に保存され、ロード バランサーによって使用され、リクエストが適切なサーバーに確実に届くようにすることで、アルゴリズムによる選択プロセスを効果的に回避します。

SSL/TLS の使用が買い物客の安全確保に不可欠な要件となったとき、同じ問題が発生しました。 SSL/TLS により、クライアントと特定のアプリケーション サーバー間の安全なセッションが可能になります。 会話の両側がその接続を介して交換されたデータを復号化して使用できることを保証するには、ロード バランサがクライアント要求を開始したのと同じサーバーに送信できる必要がありました。 セッションベースの永続性を可能にするのと同じ技術を使用して、ロード バランサーは SSL/TLS ベースの永続性をサポートできるようになりました。

使用される永続性の特定のタイプに関係なく、パターンは同じです。 セッションがすでに確立されていることを示すインジケーターが存在する場合、ロード バランサは既存の接続を尊重し、ユーザー セッションの期間中は接続が維持されるようにします。 存在しない場合は、ロード バランサは構成とアルゴリズムに基づいてリソースを選択し、接続を行います。

これは、負荷分散アルゴリズムを選択する際の容量計画に影響を与えます。 このシナリオでは、進行中のセッションによって単一のリソースが過負荷になり、他のリソースがアイドル状態になることがなくなるため、接続数を最小にするのが適切な選択です。 他のアルゴリズムでは、単一のリソースが同時に多くのユーザー セッションを維持する可能性が高く、そのサーバーにアクセスするすべてのユーザーのパフォーマンスに悪影響を及ぼします。

ホストベースの負荷分散

仮想サーバー

ホストベースの負荷分散は、最も一般的で広くサポートされているスケーラビリティ パターンの 1 つです。 すべての Web サーバーが同時に複数のホストになりすます機能をサポートしているため、これを実装するためにロード バランサーは必要ないと考えるかもしれません。 でも、あなたはそうするんです。 Web/アプリケーション サーバーは複数の仮想サーバーをホストできますが、必ずしもそれらのサーバー間で負荷分散が行われるわけではありません。 したがって、スケーリングするにはロードバランサーが必要です。 問題は、ロード バランサーがホストを分割するのか、それともそれを Web/アプリケーション サーバーに任せるのかということです。

Web/アプリ サーバー ディレクティブを使用する場合でも、外部ロード バランサーを使用する場合でも、フローは同じです。 リクエストが送信され、ターゲット (ロード バランサーまたは Web/アプリケーション サーバー) によって受信されます。 次に、ターゲット サーバーは HTTP ヘッダーを検査し、ホスト値を見つけてから、要求を適切な仮想サーバーに送信します。 

ロード バランサを使用してホストを分割する利点は、ホストに基づいてドメインを分離し、個別にスケーリングできることです。 これはより効率的であり、アプリケーションの拡張に必要なサーバー (ハードウェアとソフトウェア) の数を削減できます。 さらに、各ホスト サーバーが特定の時間に処理できる負荷をより正確に予測できるため、容量計画も容易になります。

これは、ビジネス ロジックの呼び出しに必要なコンピューティング能力が、イメージの要求に必要なコンピューティング能力とは異なるためです。 同じスケーラビリティ ドメイン内でホストを混在させると、負荷が不安定になり、容量が予測できなくなります。 ロード バランサーを使用して従来の負荷分散を提供することを選択した場合、Web/アプリケーション サーバーはホストを分割し、リクエストを適切な仮想サーバーに送信する役割を担います。 このアプローチのその他の欠点は、共有インフラストラクチャの性質によるもので、バージョンの競合やパッチ適用、アプリの更新によって仮想サーバー間で摩擦が生じる可能性がある点です。

コンテナとマイクロサービスの採用の増加により、イングレス コントローラの形式でのホストベースの負荷分散の使用が促進されています。

ルートと戻り 

レイヤー 7 (HTTP) 負荷分散

レイヤー 7 (HTTP) ロード バランシングは、その汎用性 (俊敏性?) のおかげで私のお気に入りです。 ペイロードを含むあらゆる HTTP に基づいてリクエストをロード バランスできます。 ほとんどの人は (私の意見では賢明ですが)、負荷分散ルールを HTTP ヘッダーで見つかる内容に制限しています。 これには、ホスト、HTTP メソッド、コンテンツ タイプ、Cookie、カスタム ヘッダー、ユーザー エージェントなどが含まれます。

HTTP ロード バランシングは、まずルーティングに関するもので、次にロード バランシングに関するものです。 一般的な HTTP 負荷分散パターンは、route –> distribution という形式をとります。 つまり、最初にリクエストをどの仮想サーバーに送信するかを決定し、次にアルゴリズムによってその仮想サーバーをサポートするプールからリソースを選択します。

HTTP ロード バランシングにより、API バージョンが URI (またはカスタム HTTP ヘッダー) に埋め込まれる API バージョン管理などのパターンが可能になります。 ロード バランサはバージョンを分離し、クライアントが実行のために正しいバックエンド サービスに送信されるようにすることができます。 強制的にアップグレードできない状況でも、クライアントは常に正常に移行されます。

このタイプのスケーラビリティ パターンは、機能分解やデータ分割などの他のスケーラビリティ パターンもサポートします。 これは、最も堅牢で俊敏なスケーラビリティ パターンであり、アプリやマイクロサービスのスケールアウト時に幅広いオプションを可能にします。

まとめると、5 つの主要なスケーラビリティ パターンがあり、そのほとんどを組み合わせることで (実際に組み合わせることが多いのですが)、リソースを最も効率的に使用し、可能な限り最高のパフォーマンスを実現できます。 現時点でこれらのいずれかを使用していなくても、将来使用する可能性は高いため、これらの基本的な構成を理解することは、使用しているアプリの種類や、アプリをどこに展開するかに関係なく、スケーラブルなアーキテクチャを構築するための優れた基礎となります。

スケールオン!