🦥

ロードバランサーってなんやねん

2024/07/15に公開

はじめに

どもども、インフラ案件で奮闘中の井上弥風(いのうえみふう)です。

現在プロジェクトでELB(Elastic Load Balancing)を使用しており、その内部機能を完全に理解したいと思い、この記事を書きました。

この記事について

この記事の最終的な目標は、「ELBとは何か?」を深く理解し、それを自信を持って説明できるレベルになることです。

しかし、ELBを完全に理解するためには、まず基本的なロードバランサーの概念を押さえる必要がありました。
そこで、この記事ではELBの根底にあるロードバランサーとは何かという点に焦点を当てていきます。

ELBの詳細については、この記事の後に公開予定の「ELBってなんやねん」という記事で詳しく取り上げます。
ELBに興味のある方は、ぜひそちらもご覧ください。

記事のゴール

この記事を通じて、ロードバランサーがどのようにしてトラフィックの負荷分散を行うのかを理解します。
ロードバランサーの基本的な機能と、それがなぜ重要なのかを明確にすることが目標です。

ロードバランサーとは何か?

ロードバランサーは「負荷分散装置」としても知られており、その名前が示す通り、サーバーにかかる「負荷」を適切に「バランス良く」分散させることを目的としています。

「ロード(load、負荷)」と「バランサー(Balancer、平衡を保つためのもの)」でLoad Balancerですね

そもそも「負荷」とは何なのか?

Webサイトにアクセスする画面を想像してみましょう。
例えば、私たちがZennのサイトにアクセスすると、そのリクエストはZennのサーバーに送信されます。
サーバーはリクエストに応じたデータを処理して返答します。

一人がサイトにアクセスすると、サーバーにかかる負担はそれほど大きくありません。
しかし、同時に1000人がアクセスした場合、サーバーは一気に多くのリクエストを処理する必要があります。
PCに例えると、1000個のアプリケーションが同時に動作している状態です。
普通に詰みますよね。

インターネット上での「負荷」とは、サーバーなどの機器が扱う「処理」のことを指し、先ほどの例のようにサーバーが大忙しになる状態を「高負荷」と呼びます。

ロードバランサーの役割

ロードバランサーはこのような高負荷状態を解消するために、複数のサーバーにリクエストを均等に分散させます。
例えば、1000のリクエストが来た場合、これを4台のサーバーに均等に250ずつ割り振ることができます。
それにより、各サーバーはリクエストを効率的に処理でき、全体としての応答速度を向上させることが可能です。

現実世界での例としては、ショッピングモールの駐車場係員を考えてみましょう。係員は車を駐車スペースに効率よく導くため、右や左、上の階等へと車を誘導します。
このように、駐車場の係員が車を各フロアや階に均等に割り振ることで、全体の流れをスムーズに保ちます。

同様に、ロードバランサーもサーバーにリクエストを均等に分配し、各サーバーが過負荷にならないように管理します。

ロードバランサーの主な機能

ここからは、ロードバランサーの主な機能を説明していきます。

機能①:負荷分散

ロードバランサーの核となる機能は負荷分散です。
負荷分散には以下二つの主要なアルゴリズム(手法)があります。

  1. 静的負荷分散アルゴリズム:事前に決められたルールに基づいてリクエストを分配する
  2. 動的負荷分散アルゴリズム:リアルタイムにサーバーの状態や負荷に基づいてリクエストを分配する

これにより、各サーバーへの負担が均等になり、全体の処理能力を最大限に活用できます。
(静的・動的負荷分散の詳細については後ほど説明します)

機能②:サーバーの死活監視

ロードバランサーは接続されているサーバーの稼働状態を監視し、問題が発生したサーバーを即座に検出してトラフィックの流れを調整します。
このヘルスチェック機能により、障害が発生したサーバーは自動的にトラフィックの配分から除外され、サービスの連続性が保たれます。

機能③:サーバーメンテナンスの容易性向上

ロードバランサーを利用することで、サーバーの保守作業も大幅に容易になります。

  1. ローリングアップデート
    1. 個々のサーバーを順番にメンテナンスしながらもサービスを継続的に提供できます。メンテナンス中のサーバーへのトラフィックは自動的に他のサーバーに振り分けられます。
  2. トラフィックのシフト
    1. 特定のサーバーをメンテナンスする際に、そのサーバーのトラフィックを一時的に他のサーバーへ移動させることが可能です。
  3. 可視性と監視
    1. ロードバランサーはサーバーのパフォーマンスとトラフィックのパターンを可視化し、リアルタイムでの監視を通じて問題を早期に検出し対応することができます。

ロードバランサーのメリットとデメリット

次に、ロードバランサーを利用することで得られるメリットと、注意すべきデメリットを掘り下げてみましょう。

メリット

システムダウンを防ぐ

ロードバランサーを利用するメリットの一つは、サーバーへの負荷を適切に分散させることです。
もし個々のユーザーがサーバーにアクセスするだけなら、サーバーにかかる負荷はそれほど高くなりません。
しかし、同時に数千、数万人がアクセスした場合、サーバーは過負荷状態に陥り、レスポンスが遅くなるか、最悪の場合システムがダウンする可能性があります。

ロードバランサーを導入することで、大量のトラフィックが発生しても、そのトラフィックを複数のサーバーに分散することができ、全体の処理能力を向上させます。これにより、システムのダウンリスクを大幅に減らすことが可能になります。

処理速度を向上させる

メリットの二つ目は「処理速度の向上」です。
先ほどのスーパーマーケットのレジの例を思い出してください。
15人のお客さんがいて、レジが3つある場合、各レジには5人が並び、レジ担当者は多少忙しいですが、全体としてはスムーズに処理が進みます。
しかし、もしレジが15個もあれば、お客さんはさらに迅速に買い物を済ませることができますね。

この例はロードバランサーにも当てはまります。
たとえば、ユーザー15人が3つのサーバーにアクセスする場合、各サーバーは5つのリクエストを処理します。
しかし、サーバーが15個あり、ロードバランサーが各トラフィックを均等に分散している場合、各サーバーが処理するリクエストは1つだけになります。

サーバーはユーザーからのリクエストを一つずつ処理する必要があるため、リクエスト数が多いほどレスポンス時間が長くなります。
しかし、ロードバランサーを利用することで、各サーバーの負担を軽減し、結果として全体の処理速度を向上させることができます。
このように、ロードバランサーはサーバーへのリクエストを効果的に分散させることで、システム全体のレスポンスタイムを短縮し、ユーザー体験を向上させる重要な役割を担います。

セッション維持

ロードバランサーは、利用者が一連の関連アクション(例えば、ショッピングサイトでの購入プロセス)を行う際に、同一のサーバーにアクセスを維持させる役割を持ちます。
これにより、利用者がショッピングの開始から決済までの間、同じサーバーに接続され続けることが確保されます。
これを「セッション維持」と呼び、利用者のアクセスを一貫して同じサーバーに振り分けることで実現します。

振り分け方法の選択肢

ロードバランサーは、様々なアルゴリズムを用いてリクエストをサーバーに振り分けます。主に使用される方法は次の二つです。

  1. ラウンドロビン
    1. アクセスのリクエストをすべてのサーバーに等しく分散します。例えば、6アクセス分のリクエストがある場合、3台のサーバーにそれぞれ2アクセスずつ均等に割り振ります。
  2. リーストコネクション
    1. その時点で最も接続数が少ないサーバーにリクエストを送信します。例えば、サーバーの接続数が3、1、2の場合、接続数が最少のサーバー(1)に次のアクセスを集中的に割り振ります。

他にも、サーバーの負荷比率、CPUやメモリの使用率、一定時間内のコネクション数の平均などを考慮して割り振る方法も存在します。

デメリット

ロードバランサーは多くの利点を提供しますが、導入や運用においていくつかのデメリットも存在します。

初期設定と管理の複雑さ

ロードバランサーの設定と管理は複雑であり、適切な知識がないと効果的な運用が困難になることがあります。
特に、複数のサーバーを効率良く管理するためには、負荷分散のアルゴリズムを適切に選択し、サーバーの状態を正確に把握する必要があります。
誤った設定は、逆にパフォーマンスの低下やサーバーの過負荷を引き起こす可能性があります。

コストの増加

ロードバランサーを導入することは、特に物理的なロードバランサーの場合、初期費用や維持費が高くなる可能性があります。
クラウドサービスを利用する場合でも、トラフィック量が増加するにつれてコストが増大することがあります。
そのため、小規模な環境やコストを抑えたい場合は、ロードバランサーの利用が経済的な負担になることがあります。

死活監視の詳細

死活監視とは?

サーバーにおける死活監視とは、リクエストを処理するサーバーが正常に稼働しているかを確認するプロセスです。
この死活監視の目的は、サーバーがネットワーク上でアクセス可能かつクライアントからのリクエストに対応できるかどうかを確認することです。

監視方法の具体例

Pingコマンド

死活監視の基本的な方法として、Pingコマンドがよく使われます。
Pingは、指定したIPアドレスに対して小さなデータパケットを送信し、その応答時間を測定します。
サーバーから応答が返ることで、そのサーバーがネットワーク上でアクティブであることが確認できます。
応答がない場合、サーバーに何らかの問題が生じている可能性が高いと判断されます。

HTTPリクエスト

別の一般的な監視方法として、HTTPリクエストを定期的にサーバーに送信し、応答コードや応答時間を監視する方法があります。
この方法では、サーバーが正常にHTTPリクエストに応答するかを確認し、異常な応答や応答が全くない場合は、サーバーに問題があると判断します。
これにより、サーバーの健康状態をより正確に把握することができます。

死活監視にも手法がある

サーバーの状態を確認する行為を「ヘルスチェック」と呼び、死活監視においては主にアクティブ型とパッシブ型の二つの方法があります。

  • アクティブ型ヘルスチェック:
    • この方法では、サーバーへ定期的にリクエスト(例えば、HTTP GETリクエスト)を送信し、適切な応答(通常は200 OK応答)が返ってくるかを確認します。これにより、サーバーがアクティブかつ正常に動作しているかを保証します。
  • パッシブ型ヘルスチェック
    • こちらは、クライアントからの通常のトラフィックを利用してサーバーの状態を監視します。クライアントからのリクエストに対して、サーバーからエラー応答(例えば、500系のエラー)が返ることが多くなった場合、サーバーに問題があると判断します。

その他の監視項目

ここまで死活監視の詳細を説明してきましたが、監視には死活監視以外にも以下のような監視が存在します。

  • アプリケーション監視
    • アプリケーションの実行時間、応答時間、エラー率などを監視し、アプリケーションのパフォーマンスを評価します。
  • パフォーマンス監視
    • システムのCPU使用率、メモリ使用率、ネットワーク使用率などを監視し、全体のシステムパフォーマンスをチェックします。
  • ログ監視
    • システムやアプリケーションから出力されるログを分析し、エラーや異常がある場合にはアラートを通じて管理者に連絡をしたり、必要な対応を行います。

静的分散方式と動的分散方式

ロードバランサーがリクエストを各サーバーに振り分ける方法には、「静的分散方式」と「動的分散方式」があります。
これらの方式はロードバランサーの「頭脳」のようなもので、どのリクエストをどのサーバーに転送するかを決定します。

具体的に見ていきましょう。

静的分散方式

静的分散方式とは、ロードバランサーが決められた順序で各リクエストを各サーバーに振り分ける方式です。

静的分散方式と聞くと何やら難しく感じますが、つまりは「各サーバーに割り振るリクエスト量を事前に決めておいて、システム稼働中はそのルールに基づいてロードバランサーが各サーバーにリクエストを転送する」方式が「静的分散方式」です。

例えば、リクエストが6個あり、3台のサーバーがある場合、リクエストは次のように分配されます:

  • 1番目: サーバーA
  • 2番目: サーバーB
  • 3番目: サーバーC
  • 4番目: サーバーA
  • 5番目: サーバーB
  • 6番目: サーバーC

上記は静的分散方式の一例ですが、上記のように各サーバーに順次処理を分散すると「事前に決める方式」が静的分散方式です。

そんな静的分散方式の中にも、リクエストを振り分ける方法として二つの振り分け方式があります

  1. ラウンドロビン
  2. 重み付きラウンドロビン

一つずつ見ていきましょう。

ラウンドロビン

「ラウンドロビン」方式は先ほど挙げた通り、各サーバーに決められた順序でリクエストを振り分ける方式です。

  • 1番目: サーバーA
  • 2番目: サーバーB
  • 3番目: サーバーC
  • 4番目: サーバーA
  • 5番目: サーバーB
  • 6番目: サーバーC

この方式が効果的なのは、次の二つの条件が満たされている時です

  1. 各サーバーの処理能力が同じであること
  2. 各リクエストの処理量が同じ(くらい)であること

なぜ上記の二つの条件が満たされていないといけないのでしょうか?

例として、サーバーAとサーバーBが高性能で、サーバーCだけが低性能な状況を考えてみましょう。
これは新卒一年目の社員さん(サーバーC)にベテラン上司(サーバーAとB)と同じ仕事量を同じペースで振るのと同じで、現実的には難しい部分がありますよね。

同様に、サーバーCだけに重いリクエストが集中すると、サーバーダウンのリスクが高まります。
そのため、1番の「各サーバーの処理能力が同じであること」が重要なのです。

また、2番の「各リクエストの処理量が同じ(くらい)であること」というのもラウンドロビン方式において重要です。

何故かというと、例として各サーバーの処理能力は同じでも、サーバーCにだけ高負荷な処理をする必要があるリクエストが連続できたらどうでしょうか?
数回程度なら問題ありませんが、これが一継続的に来るとサーバーは最悪ダウンしてしまいます。

そのため、各サーバーの処理能力が同程度で、かつ各リクエストの内容が比較的同じ重さの場合、ラウンドロビン方式は有効に働きます。

重み付きラウンドロビン

「重み付きラウンドロビン方式」は、各サーバーの処理能力に応じてリクエストの割り振り比率を調整する方法です。
この方式を現実世界に例えると、あなたが三人の部下を持っているとします。
Aさんは非常に効率的で、BさんとCさんも優秀ですが、Aさんほどではありません。

もしAさんと同じペースでBさんとCさんにも仕事を割り振ると、彼らは過負荷になってしまいます。
そこで、Aさんには多くのタスクを、BさんとCさんには少し少なめのタスクを割り振ることで、全体としてのタスクのバランスを取ります。

この「各サーバーごとに割り振るリクエスト量を事前に決めておく方式」が重み付きラウンドロビンです。

重み付きラウンドロビンはサーバーごとに割り振るリクエスト量を事前に決めておける点が特徴ですが、そのためには各サーバーの処理能力を設計者が明確に把握しておく必要があります。

ラウンドロビン・重み付きラウンドロビンで共通していること

ラウンドロビンと重み付きラウンドロビンは、リクエストの割り振りルールが静的に設定される点で共通しています。
つまり、一度設定されたルールに基づいてリクエストが割り振られ、実行時には変更されません。
このため、特定のサーバーが高負荷な状態になっても、トラフィックの分散方法は変わらないのです。
これに対して、動的分散方式では、サーバーの状態をリアルタイムで評価し、トラフィックを適切に割り振ることが可能です。

つまり、動的に負荷分散を切り替えることができないのが静的分散方式で、逆に動的にサーバーの状態を見つつトラフィックを割り振るのが動的分散方式です。

ここからは動的分散方式について詳しく見ていきましょう。

動的分散方式

動的分散方式は、静的分散方式と異なり、「リクエストを受け取るたび」に、サーバーやネットワークの現状を考慮して、リクエストを転送するサーバーを決定します。
この方法により、以下のような状況でも効果的にトラフィックを処理することが可能です。

  1. 分散対象のサーバーごとに処理能力が異なる場合
  2. リクエストごとに必要な処理時間が異なる場合

動的分散方式には以下のような分散方式がありますが、ここでは「最小コネクション数方式」と「最小応答時間方式」について説明します。

  1. 最小コネクション数
  2. 重み付き最小コネクション数
  3. 最小クライアント数
  4. 最小データ通信量
  5. 最小応答時間
  6. 最小サーバ負荷

最小コネクション数方式

最小コネクション数方式では、アクティブなコネクション数が最も少ないサーバーに新しいリクエストを転送することで、トラフィックを分散します。
これにより、各サーバーの負荷を均等に保つことができます。

例えば、クライアントからロードバランサーに2つのリクエストが送信されたとします。
この時、ロードバランサーは「サーバーA」と「サーバーB」にリクエストを転送し、「サーバーC」にはリクエストを転送させないとします。

この状況で新しいリクエストが到着した場合、ロードバランサーはアクティブなコネクション数を確認し、最もコネクション数が少ないサーバーにリクエストを割り当てます。
サーバーCにはまだコネクションがないため、この新しいリクエストはサーバーCに転送されます。

この方式を採用することで、サーバー間での負荷の偏りを防ぎ、システム全体の効率を向上させることが可能です。

最小応答時間方式

最小応答時間方式は、サーバーごとの応答時間が最も短いものにリクエストを優先的に割り振る方法です。
この方式では、サーバーの処理能力が異なる場合でも効率的にトラフィックを管理できます。
具体的には、応答速度が速いサーバーがより多くのリクエストを受け取ることになるため、全体のパフォーマンスとユーザーエクスペリエンスを向上させることが可能です。

たとえば、レストランでの待ち時間を最小限に抑えるために、最も効率的に注文を処理できるウェイターに新しい顧客を割り当てるのと似ています。
これにより、顧客は早くサービスを受けることができ、全体の満足度が向上します。

DNSラウンドロビンとは?

先ほど、静的分散方式の一つである「ラウンドロビン」について説明しました。
このラウンドロビンと似た名前として「DNSラウンドロビン」というものが存在します。

ラウンドロビンとDNSラウンドロビンの区別を明確にすることは、ロードバランサーの理解をより深くしていく上で重要なため、ここからはDNSラウンドロビンとは何かを具体的に見ていきます。

DNSラウンドロビンを理解するにはまず下記の四つの概念を理解する必要があるため、順に見ていきましょう

  1. IPアドレス
  2. ドメイン名
  3. DNS
  4. DNSサーバー

IPアドレス

IPアドレスは、インターネット上の各デバイスの「住所」のようなものです。
私たちが住んでいる住所が、自宅がどこにあるかを示す位置情報を提供するように、ネットワーク上の各デバイスも固有の住所を持っています。
このデジタル住所がIPアドレスです。たとえば、あなたの家の住所が「東京都新宿区1-1-1」であるように、あるコンピュータのIPアドレスは「192.0.2.1」のようになります。

簡単に言えば、IPアドレスはネットワーク上にある特定のコンピューターの場所を示す住所ですね。

ドメイン名

ドメイン名は、IPアドレスに対して人間が理解しやすい名前を割り当てたものです。
例えば、「192.0.2.1」という数字の羅列を覚えるのは難しいですが、「https://example.com」という名前なら覚えやすいですね。ドメイン名はこのように、数字のIPアドレスに代わる、人に親しみやすい形式の文字列です。

IPアドレスとドメイン名は結果的には、インターネット上の同じ場所を指し示していますが、人間にとって理解しやすい形で表されるのがドメイン名です。

単に「IPアドレスだと人間は理解しにくいからそれを文字列で表しているものがドメイン名だぜ!!」という理解でOKです^^

DNSとDNSサーバー

先ほど説明した通り、ドメイン名はIPアドレスを人間が理解しやすい形にしたものです。
インターネットを利用する際、我々は通常、URLを基に必要な情報を検索します。
この時、裏で活躍するのがDNSサーバーです。

たとえば、「https://gorira.com」をブラウザに入力すると、PCさんは次のような態度を示します。
このURLが何を意味しているのかわからないよ!インターネット上での正しい住所はIPアドレスなんだ。それを教えてくれないと困るよ!

そこで、PCさんはDNSサーバーに助けを求めます。
「ねえ、https://gorira.comっていうURLに対応するIPアドレスを知ってる? そのIPアドレスにあるサーバーにアクセスして、そのサイトの情報を表示したいんだけど…」

DNSサーバーはその問い合わせに応じて、「https://gorira.com」に対応するIPアドレスをPCに教えます。

これによって、ブラウザは正しいサーバーにアクセスして、ウェブサイトの情報を取得し、最終的にはPCの画面に表示します。

重要な点は、「DNS」とはドメイン名とIPアドレスを関連付ける仕組みであり、この仕組みに基づいて動作するサーバーが「DNSサーバー」であるということです。
DNSは仕組み自体を指し、DNSサーバーはその仕組みを具現化した実際のサーバーです。

DNSラウンドロビンとは何なのか

これまでにIPアドレス、ドメイン名、DNS、そしてDNSサーバーについて説明してきました。
次に、DNSラウンドロビンの概念を詳しく見ていきましょう。

通常のDNSサーバーの挙動

DNSサーバーは、特定のドメイン名に紐づく一つのIPアドレスを返すことが基本です。
つまり通常のDNSサーバーはIPアドレスとドメイン名を一対一の関係性でしか管理できないのです。

しかし、あるURLに複数のIPアドレスが紐づけられている場合はどうなるのでしょうか?
そもそもそんなことはあり得るのでしょうか??
実際にはあり得ます。

例えば、「たこやっきー」という架空のウェブサービスがあり、金曜日と土曜日に多くの人が訪れるため、これらの日にアクセスが急増します。
一台のサーバーでは全てのアクセスを処理することができないため、複数のサーバーに負荷を分散させる必要があります。

DNSサーバーが「https://takoyakki.com」というURLに紐づくIPアドレスを一つしか返さないと、全てのアクセスが同じサーバーに集中してしまい、効率的な負荷分散ができません。

DNSラウンドロビンの役割

ここでDNSラウンドロビンが活躍します。
DNSラウンドロビンは、同じドメイン名に複数のIPアドレスを割り当てることで、リクエストをそれぞれのサーバーに均等に分散させる技術です。
これにより、負荷を効果的に分散させ、サービスの可用性とパフォーマンスを高めることができます。

https://takoyakki.com」に対して、DNSサーバーは複数のIPアドレスを順番に返すことで、リクエストを複数のサーバーに均等に割り当てることが可能になります。この仕組みにより、どのサーバーも過負荷になることなく、ユーザーに安定したサービスを提供できます。

結論として、通常のDNSサーバーもDNSラウンドロビンもDNSという仕組みを基に機能するDNSサーバーであることに違いはありません

しかし、DNSサーバーがドメイン名とIPアドレスを一対一でしか管理しないのに対して、DNSラウンドロビンは一つのドメイン名に対して複数のIPアドレスを関連付けることができるという点が違います。

ロードバランサーとDNSラウンドロビンの関係性

ロードバランサーとDNSラウンドロビンはよく一緒に語られますが、その機能は基本的に異なります。
ロードバランサーはトラフィックを受け取り、動的にサーバーの状態を考慮してトラフィックを適切なサーバーにルーティングします。
一方で、DNSラウンドロビンはあくまでDNSの仕組みを利用して、複数のIPアドレスを順番に返すことで負荷分散を図る方法です。

DNSラウンドロビンは、複数のサーバーにドメイン名をマッピングすることにより、ロードバランサーとしての機能を果たしますが、これはあくまで静的な方法であり、サーバーの実際の負荷や状態を考慮しません。
そのため、「DNSラウンドロビンはロードバランサーか?」という問いに対しては、「部分的にはその機能を果たしているが、本来のDNSサーバーとしての役割も持っている」と答えることができます。

まとめ

ここまでロードバランサーについての詳細を書いてきましたが、ロードバランサーとは簡潔に言うと負荷分散装置です。

そして、負荷分散装置の中にも静的・動的な分散方法があったり、DNSサーバーが一部ロードバランサーとしての機能を果たしているDNSラウンドロビンという存在についても理解できました。

ここまではロードバランサーの詳細を書いてきましたが、次に公開する予定の記事は「ELBってなんやねん」という記事で、この記事を基に理解する最終的なゴールです。

ここまで読んでくださった読者の皆様、ありがとうございました!!

良かったらTwitterフォローしてねっ
https://twitter.com/mi_01_24fu

Discussion