SA.03.2 負荷分散と回復, 障害局所化 (重要度: 5)

ロードバランサの主要な種類と, それぞれの基本的な設定

L4ロードバランサとL7ロードバランサは、両者ともネットワークトラフィックをバックエンドサーバーに均等に分散するための装置ですが、その振り分けの粒度に違いがあります。

L4ロードバランサは、ネットワークレイヤ(トランスポートレイヤ)でのトラフィックを制御します。具体的には、IPアドレス、ポート番号、およびトランスポートプロトコル(TCPやUDPなど)に基づいてトラフィックを分散させます。L4ロードバランサでは、パケットのヘッダ情報のみを見て振り分けを行うため、リクエストの内容には直接アクセスできません。

一方、L7ロードバランサは、アプリケーションレイヤ(アプリケーションレイヤ)でのトラフィックを制御します。具体的には、HTTPヘッダ、URI、クエリパラメータなどのようなリクエストの内容に基づいてトラフィックを振り分けます。L7ロードバランサは、リクエストの内容を詳細に解析するため、特定のリクエストヘッダやパラメータに基づいてトラフィックを分散させることができます。

したがって、L4ロードバランサは主にネットワークレベルでのトラフィック分散に使用され、トランスポートプロトコル(TCPやUDP)に基づいて振り分けます。一方、L7ロードバランサはアプリケーションレベルでのトラフィック分散に使用され、リクエストの内容に基づいて詳細な振り分けを行います。どちらのロードバランサを選択するかは、アプリケーションの要件やトラフィックの特性によって異なります。

L4 ロードバランサ, 及びそのパケット転送方式

L4 ロードバランサは、ネットワークトラフィックを複数のバックエンドサーバに分散させるための装置です。これにより、サーバの負荷を均等に分散し、可用性とパフォーマンスを向上させることができます。L4 ロードバランサは、さまざまなパケット転送方式を使用してバランシングを実現します。以下に代表的な方式を説明します。

  1. NAT (Network Address Translation):
    NAT方式は、ロードバランサがパケットのソースアドレスを変更して、トラフィックをバックエンドサーバに転送します。クライアントからのリクエストは、ロードバランサのパブリックIPアドレスを宛先として送信され、ロードバランサが内部ネットワーク上のバックエンドサーバにパケットを転送します。バックエンドサーバからの応答も同様に、ロードバランサがソースアドレスを変更してクライアントに転送します。
  2. Direct Server Return (Direct Routing):
    DSR方式では、ロードバランサがクライアントからのリクエストをバックエンドサーバに転送する際に、パケットの宛先IPアドレスを変更せずにそのまま転送します。バックエンドサーバはリクエストを処理し、応答をクライアントに直接送信します。この方式では、ロードバランサはトラフィックの出口として機能し、バックエンドサーバは直接トラフィックに応答します。
  3. Tunneling:
    トンネリング方式では、ロードバランサはクライアントとバックエンドサーバの間に仮想的なトンネルを構築し、パケットを転送します。ロードバランサはパケットを受け取り、パケットに新たなヘッダを追加してバックエンドサーバに転送します。バックエンドサーバはトンネルの終点でパケットを受け取り、処理結果をロードバランサに返します。ロードバランサは最終的に処理結果をクライアントに返信します。
  4. Local Node:
    Local Node方式は、ロードバランサがリクエストを処理するのではなく、ロードバランサ自体がバックエンドサーバとなります。ロードバランサはネットワークトラフィックを完全に受け持ち、サーバとしての機能を提供します。この方式は、ロードバランサ自体の性能が高く、スケーラビリティを考慮する必要がない場合に使用されます。

L7 ロードバランサ, 及びその振り分け規準

L7 ロードバランサは、ネットワークトラフィックを複数のバックエンドサーバに分散させるための装置です。L7 ロードバランサは、リクエスト内容に基づいてトラフィックを振り分けることができます。以下に代表的な振り分け規準を説明します。

  1. URI (Uniform Resource Identifier):
    URIは、リクエストの一部であるURLの一意のアドレスを指します。L7 ロードバランサは、リクエストのURIパスを鑑別基準として使用して、バックエンドサーバにトラフィックを振り分けます。例えば、特定のURIパスが/public/で始まるリクエストは、バックエンドサーバAに、/api/で始まるリクエストはバックエンドサーバBに振り分けることが可能です。
  2. リクエストパラメータ:
    リクエストパラメータは、URLに付加される追加情報を指します。L7 ロードバランサは、リクエストパラメータの内容を鑑別基準として使用して、バックエンドサーバにトラフィックを振り分けます。例えば、queryパラメータの値に基づいて振り分けを行うことがあります。たとえば、lang=jaのパラメータがあるリクエストは、バックエンドサーバAに、lang=enのパラメータがあるリクエストはバックエンドサーバBに振り分けることができます。
  3. HTTPヘッダ:
    HTTPヘッダは、リクエストのメタデータや追加情報を含んでいます。L7 ロードバランサは、リクエストのヘッダ情報を鑑別基準として使用して、バックエンドサーバにトラフィックを振り分けます。例えば、User-Agentヘッダの値に基づいて振り分けることがあります。特定のUser-Agentがモバイルデバイスからのリクエストを示す場合、バックエンドサーバAに振り分け、それ以外の場合はバックエンドサーバBに振り分けることができます。

これらの振り分け規準は、リクエストの内容を鑑別するために使用されます。柔軟な振り分けを実現するために、複数の規準を組み合わせて使用することもできます。L7 ロードバランサを使用することで、トラフィックを効果的に複数のバックエンドサーバに振り分けることができます。

接続スケジューリング

それぞれの接続スケジューリングは、ロードバランサがバックエンドサーバーへの接続を確立する方法を決定するために使用されるアルゴリズムです。

  1. ラウンドロビン(Round Robin): ラウンドロビンは、接続を複数のサーバーに循環的に均等に分散させるアルゴリズムです。最初の接続はサーバー1に、次の接続はサーバー2に、その後はサーバー3、サーバー4…というように順番に接続が行われます。この方法は、負荷を均等に分散するため、ネットワークトラフィックが一様に増加する場合に効果的です。
  2. 最小接続(Least Connection): 最小接続は、現在接続数が最も少ないサーバーに接続を振り分けるアルゴリズムです。この方法は、リクエストが時間的に偏っている場合や、一部のサーバーの負荷が高い場合に有効です。最小接続アルゴリズムにより、接続数が少ないサーバーにリクエストを送ることによって、負荷をバランスさせることができます。
  3. 最小通信量(Least Traffic): 最小通信量は、現在の接続状況に基づいてデータ転送量の少ないサーバーに接続を割り当てるアルゴリズムです。これにより、ネットワークの帯域幅を効果的に使用することができます。最小通信量アルゴリズムは、リクエストによって生成される応答のサイズを考慮して接続を制御するため、ネットワークのトラフィック量を最小限に抑えるという利点があります。

これらの接続スケジューリングアルゴリズムは、サーバーへの負荷の偏りを解消し、リクエストの処理を効率化するために使用されます。どのアルゴリズムが最適かは、アプリケーションの要件やトラフィックの特性によって異なります。

バックエンドのヘルスチェック

バックエンドのヘルスチェックは、ロードバランサがバックエンドサーバーの状態を監視し、正常に応答しているかどうかを確認する機能です。これにより、ロードバランサはトラフィックを正常に処理できるサーバーのみに接続することができます。

バックエンドのヘルスチェックでは、定期的にバックエンドサーバーに対してリクエストを送信し、応答が成功したかどうかを確認します。応答が成功した場合は、サーバーが正常に動作していると判断されます。一方、応答がタイムアウトしたり、エラーコードが返されたりする場合は、サーバーがダウンしているか、正常に動作していないとみなされます。

ヘルスチェックの頻度やタイムアウト値、応答条件などは、具体的な設定によってカスタマイズすることができます。また、ヘルスチェックが失敗した場合には、ロードバランサはそのサーバーへの接続を停止し、他の正常なサーバーにトラフィックを振り分けます。

バックエンドのヘルスチェックは、システムの可用性と耐久性を向上させるために重要です。障害が発生した場合でも、ヘルスチェックにより問題のあるサーバーからの接続を回避することができます。これにより、ユーザーエクスペリエンスの向上とシステムへの信頼性の向上が実現されます。

負荷分散クラスタの割り当て, スケジューリング, ヘルスチェック

IPVS (LVS)

IPVS(Internet Protocol Virtual Server)は、Linuxカーネル内で動作する負荷分散機能です。IPVSを使用して構築された負荷分散クラスタでは、以下のプロセスが行われます。

  1. 割り当て(Configuration): IPVSは、負荷分散に使用する仮想IPアドレス(VIP)とポート番号、およびバックエンドサーバーのIPアドレスとポート番号の組み合わせを設定します。VIPはクライアントに公開され、バックエンドサーバーに対してリクエストを転送します。
  2. スケジューリング(Scheduling): IPVSでは、リクエストをどのバックエンドサーバーに転送するかを決定するためのスケジューラが使用されます。さまざまなスケジューリングアルゴリズム(ラウンドロビン、ウェイトランダム、およびハッシュ法など)が利用でき、適切なアルゴリズムを選択することで、リクエストを効果的にバランシングすることができます。
  3. ヘルスチェック(Health Checking): IPVSは、バックエンドサーバーのヘルスチェックを定期的に実行し、応答が受信できるかどうかを確認します。これにより、障害が発生した場合には、ヘルスチェックに失敗したサーバーへのトラフィックが停止し、正常なサーバーにのみリクエストが転送されるようになります。ヘルスチェックは、リクエスト送信、期待される応答をチェック、タイムアウトやエラーの発生など、さまざまな方法で行うことができます。

IPVS(LVS)は、可用性、耐久性、スケーラビリティを向上させるための強力なツールです。負荷の分散により、バックエンドサーバーへの負荷が均等に分散され、障害時にはセマフォトラフィックが停止され、サービスの唯一性が実現されます。

HAProxy

HAProxyは、オープンソースのロードバランサーであり、負荷分散クラスタの構築に使用できます。以下のプロセスが行われます。

  1. 割り当て(Configuration): HAProxyでは、バランシングのために使用するフロントエンドとバックエンドを設定します。フロントエンドは、クライアントからのリクエストを受け付け、バランシングのルールを適用します。バックエンドは、実際のサーバーグループに対してトラフィックを転送します。また、フロントエンドとバックエンド間の設定、ポート番号、バランシングアルゴリズムなども定義します。
  2. スケジューリング(Scheduling): HAProxyでは、リクエストをどのバックエンドサーバーに転送するかを決定するためのスケジューリングアルゴリズムが使用されます。HAProxyでは、多くのスケジューリングアルゴリズム(ラウンドロビン、ウェイトランダム、最少接続、およびソースIPなど)を選択できます。
  3. ヘルスチェック(Health Checking): HAProxyでは、バックエンドサーバーの可用性を監視するためのヘルスチェックを実行します。これにより、ヘルスチェックに失敗したサーバーへのトラフィックが自動的に停止し、正常なサーバーにのみリクエストが転送されるようになります。ヘルスチェックは、定期的なリクエストの送信や期待される応答の確認など、様々な方法で行うことができます。

HAProxyを使用することで、負荷分散クラスタはより高い可用性、耐久性、およびスケーラビリティを持つことができます。バックエンドサービスのトラフィックが均等に分散され、障害が発生した場合には自動的に回避されます。これにより、システムのパフォーマンスと信頼性が向上します。

DNS ベースの負荷分散 (広域負荷分散) 

ルーティングポリシー

以下は、異なるルーティングポリシーの説明です。

  1. 重み付きラウンドロビン(Weighted Round Robin): このポリシーでは、バックエンドサーバーに重みを割り当てます。重みは、サーバーの処理能力を示し、重みの高いサーバーはより多くのトラフィックを受けます。重み付きラウンドロビンは、負荷の均等な分散を実現するために使用されます。
  2. 最小接続(Least Connections): このポリシーでは、バックエンドサーバーの接続数を監視します。リクエストが到着するたびに、最も接続数の少ないサーバーにトラフィックを送信します。これにより、負荷の偏りがなくなり、リクエストの迅速かつ効率的な処理が可能になります。
  3. ジオロケーション(Geolocation): このポリシーでは、クライアントのIPアドレスやその他の地理的情報を使用して、最適なバックエンドサーバーを選択します。クライアントの位置に基づいて、可能な限り近いサーバーへのリクエストをルーティングすることで、遅延やネットワークの問題を回避できます。
  4. 近接アルゴリズム(Proximity Algorithms): 近接アルゴリズムは、複数の地理的に分散したデータセンターやサーバーファーム間のネットワークレイテンシを最小限に抑えるために使用されます。これにより、リクエストが最も近いサーバーにルーティングされ、ユーザー体験の向上が図られます。近接アルゴリズムには、レイテンシベースやRTT(ラウンドトリップタイム)ベースのものなど、いくつかのバリエーションがあります。

監視ツールと組み合わせによるルーティングの動的設定

監視ツールや組み込みのモニタリング機能を使用することで、ルーティングの動的設定を実現することができます。以下にその仕組みを説明します。

  1. 監視ツールのセットアップ:まず、監視ツールをセットアップして適切なパラメータを設定します。これには、対象となるネットワークまたはサーバーのパフォーマンス指標や健全性指標を監視するための設定が含まれます。
  2. 監視データの収集:監視ツールは、定期的に対象となるシステムやネットワークからデータを収集します。これには、レイテンシ、応答時間、トラフィックの量などの指標が含まれます。
  3. ルーティングポリシーの評価:収集されたデータを使用して、事前に設定されたルーティングポリシーと現在の状況を比較します。たとえば、最小接続ポリシーを使用している場合、監視データから接続数の最も少ないサーバーを特定します。
  4. ルーティングポリシーの調整:常に最適なルーティングを実現するために、監視データに基づいてルーティングポリシーを調整する必要がある場合があります。たとえば、トラフィックが急増している場合は、重み付きラウンドロビンポリシーによって処理能力の高いサーバーに負荷を分散させることができます。
  5. ルーティングの自動化:監視ツールは、収集したデータや調整したルーティングポリシーを自動的に適用する機能を提供する場合があります。自動化により、リアルタイムのモニタリングや障害時の自己回復などが可能になります。

このような方法を使用することで、ネットワークやシステムの状態に応じてルーティングの設定を自動的に調整できます。これにより、効率的なトラフィックの分散管理が実現され、高パフォーマンスや冗長性の向上が期待できます。

メッセージングキューを介した非同期処理

伝達方法

非同期処理では、pull 方式と push 方式の2つのオプションを使用することができます。以下にそれぞれの方法の説明をします。

  1. Pull 方式:
    Pull 方式では、メッセージの受信側(コンシューマ)がアクティブにメッセージキューをポーリングし、メッセージを自分で取得します。コンシューマは、メッセージキューにリクエストを送信し、メッセージが利用可能になると応答します。その後、コンシューマはメッセージを取得して処理します。

この方式の利点は、コンシューマが処理できるだけのメッセージを適切なタイミングで受け取ることができることです。また、コンシューマは必要に応じて自分のペースでメッセージを処理できます。一方で、連続してポーリングを行う必要があり、効率が低下する可能性があるというデメリットもあります。

  1. Push 方式:
    Push 方式では、メッセージの送信側(プロデューサ)がメッセージをメッセージキューに直接送信します。メッセージキューはメッセージが利用可能になると、自動的にコンシューマに通知します。そして、コンシューマは通知を受け取ると即座にメッセージを受信し処理します。

この方式の利点は、ポーリングの必要がないため、リソースの使用効率や応答性が向上することです。また、メッセージの届けるタイミングを確実に制御できます。しかし、プロデューサがコンシューマの状態を考慮せずにメッセージを送信するため、コンシューマが処理能力を超えることがあるというデメリットもあります。

QoS

QoS(Quality of Service)は、メッセージングシステムにおいてメッセージの配信品質を制御するための機能です。以下にそれぞれのQoSの説明をします。

  1. At-least-once:
    At-least-once(少なくとも一度)は、メッセージの配信が最低でも一度は行われることを保証するQoSです。この方法では、メッセージが送信元から受信先まで確実に届けられますが、可能な場合にはメッセージの重複が発生することがあります。重複を処理するために、メッセージの受信側は適切な副作用のない操作(かぎりなく冪等な処理)を実行する必要があります。
  2. Exactly-once:
    Exactly-once(正確に一度)は、メッセージの配信が厳密に一度のみ行われることを保証するQoSです。この方法では、メッセージが送信元から受信先まで一度だけ届けられます。メッセージングシステムは、アクノリッジメントやトランザクションといったメカニズムを使用して、重複を防止します。正確な一度の配信を達成するためには、システムのコンポーネント間で高度な同期とトランザクションの管理が必要です。
  3. At-most-once:
    At-most-once(最大で一度)は、メッセージの配信が一度以下で行われることを保証するQoSです。この方法では、メッセージの配信が保証されませんが、メッセージが重複することはありません。メッセージの処理が完了する前に通信エラーや障害が発生した場合、メッセージは失われる可能性があります。このQoSは、データの重複を許容できる場合に適していますが、信頼性が重要なシナリオでは適切ではありません。

それぞれのQoSは、メッセージングシステムの設計と要件によって異なる利点と制約を持っています。重要な要素は、データの確実な配信を必要とするかどうか、処理の冪等性が実現できるかどうか、さらにはパフォーマンスの要件などです。適切なQoSを選択するには、プロジェクトのニーズを評価し、いくつかの要素を考慮する必要があります。

障害検知とリトライ

障害検知とリトライ:
障害検知とリトライは、メッセージングシステムにおいてメッセージの配信を確保するために使用される方法です。メッセージが送信元から受信先に正常に配信されなかった場合、障害検知機構はその状況を検知し、リトライを行います。障害検知は、メッセージングシステムが相手の状態をモニタリングして、配信の成功または失敗を判断するプロセスです。リトライは、障害が検知された場合にメッセージを再送することを指します。

指数バックオフとジッターを用いたリトライ:
指数バックオフとジッターは、リトライされるメッセージの送信間隔を制御するために使用される手法です。指数バックオフは、メッセージのリトライ間隔を増加させる方法です。つまり、リトライごとに待ち時間が増えていきます。これにより、送信先システムの過負荷を緩和し、リトライ処理の成功率を向上させることができます。ジッターは、リトライ間隔にランダムな変動を加えることで、ネットワークやシステムの通信パターンの規則性を排除し、ボトルネックを回避します。指数バックオフとジッターを組み合わせることで、メッセージングシステムに冗長性と耐性をもたせることができます。

デッドレターキュー:
デッドレターキューは、障害が発生しメッセージの正常な配信が困難な場合に使用されるメッセージングの機能です。通常、デッドレターキューは、リトライ回数やリトライ間隔の上限を超えたメッセージを格納するために使用されます。障害が解消された後に、コンシューマーがデッドレターキューからメッセージを再試行したり、エラーハンドリングを行ったりすることができます。デッドレターキューは、多くの場合、エラーや例外が発生した場合に追加の情報を提供するためのエラーログ記録としても利用されます。

これらの機能を組み合わせることで、メッセージングシステムは信頼性と耐障害性を確保し、メッセージの確実な配信を促進できます。障害発生時には、適切なリトライメカニズムとデッドレターキューの活用が重要です。

サービスレベル維持, 部分的な稼働維持のための設計

監視に基づく仮想マシンやコンテナの自動再起動・ノード数維持

監視に基づく仮想マシンやコンテナの自動再起動・ノード数維持は、アプリケーションやインフラストラクチャの可用性を確保するために利用される方法です。

仮想マシンやコンテナには、オートスケーリング(自動スケーリング)やヘルスチェックといった機能が備わっており、これらを利用して監視を行います。監視は、リソース使用状況、応答時間、エラーレートなどの指標を監視し、システムの正常性を評価します。

監視に基づく仮想マシンやコンテナの自動再起動は、定期的なヘルスチェックを実施し、異常が検出された場合に自動的に仮想マシンやコンテナを再起動する仕組みです。これにより、システムの可用性を高め、障害発生時にも迅速な復旧が可能になります。

ノード数維持は、オートスケーリング機能を利用して、アプリケーションやサービスに必要なノード数を自動的に調整することを指します。監視を通じて、システムの負荷やリソース使用率を監視し、必要な場合には新たなノードを追加したり、負荷が減少した場合にはノードを削除したりします。ノード数維持によって、システムは必要なリソースを適切に利用することで、パフォーマンスと可用性のバランスを保ちます。

これらの仕組みによって、インフラストラクチャやアプリケーションの監視と自動制御が実現されます。アプリケーションやサービスにおける障害への素早い対応や、需要の変動に柔軟に対応する能力を向上させることができます。

重要機能の優先的維持

スロットリングとサーキットブレーカーは、重要な機能の優先的な維持と可用性を確保するために利用されるメカニズムです。

スロットリングは、システムの負荷を管理するための制御手法です。システムのリクエスト数やトラフィックの量を制限することで、リソースの過負荷やパフォーマンスの低下を防ぎます。スロットリングは、リクエスト数やトラフィックの著しい増加が予想される場合や、特定のエンドポイントや機能に対して公平なリソース配分を行いたい場合に使用されます。例えば、APIプロバイダーは、特定のクライアントが大量のリクエストを送信して他のクライアントのパフォーマンスを低下させることを防ぐために、一定期間内の最大リクエスト数を制限します。

サーキットブレーカーは、システムの障害やパフォーマンスの低下への対応手法です。サーキットブレーカーは、クライアントとサーバーの間に挿入され、システムの応答時間やエラーレートなどの指標を監視します。もしシステムに異常な振る舞い(例:エラー応答率の増加)が検出されると、サーキットブレーカーは一時的にそのサービスへのリクエストをブロックし、バックエンドのシステムに対して負荷をかけないようにします。これにより、バックエンドシステムの負荷や障害を制御し、全体の可用性とパフォーマンスを向上させることができます。また、サーキットブレーカーは、障害が解消したと検出した場合に再試行を再開することもできます。

これらの機能は、システムの過負荷や障害への順応性を向上させ、重要な機能の優先的な維持とユーザーエクスペリエンスの向上に役立ちます。