ロードバランシング(負荷分散)とは? 基礎からわかりやすく解説

アクセスが急増してもサイトが落ちないのはなぜか、ロードバランサーがどう振り分け先を決めているのかを見ていきましょう。

ロードバランシングとは何か

1台のサーバーに集中しがちなトラフィックを複数のサーバーに分散させることで、特定のサーバーに障害が起きてもサービス全体が止まらないようにする技術です。ロードバランサーは複数のサーバー群の手前に立ち、すべてのリクエストを受け取って、その時点で最も適したサーバーへ振り分けます。

ラウンドロビン方式

最もシンプルで広く使われている振り分け方式で、リクエストが来るたびにサーバーA→B→C→Aの順番で機械的に割り当てます。実装が簡単で、各サーバーの性能が近い場合には有効ですが、サーバーごとの処理能力や現在の負荷状況は考慮されません。

最小接続数方式

順番に割り当てるのではなく、現在処理中の接続数が最も少ない、つまり最も空いているサーバーに新しいリクエストを送る方式です。ファイルアップロードのように処理時間が大きくばらつく場合に、ラウンドロビンより均等な分散が可能になります。

IPハッシュ(セッション維持)方式

クライアントのIPアドレスのハッシュ値をもとに、常に同じサーバーへ接続を振り分ける方式です。ログイン情報を特定のサーバーのメモリだけに保存している場合、IPハッシュを使わないと後続のリクエストが別のサーバーに割り振られてログアウトしてしまうことがあります。ただし、社内ネットワークのように多くの利用者が同じIPアドレスを共有していると、特定のサーバーに負荷が偏るという弱点もあります。

L4ロードバランサーとL7ロードバランサーの違い

L4(トランスポート層)ロードバランサーはIPアドレスとポート番号しか見ないため高速に処理できますが、単純な基準でしか振り分けられません。L7(アプリケーション層)ロードバランサーはURLパスやブラウザの種類まで解析でき、「/images」宛てと「/api」宛てを別のサーバー群に振り分けるといった精密な制御が可能で、機能ごとにサーバーを分けたマイクロサービス構成に特に有用です。

ヘルスチェック

ロードバランサーは一定間隔で各サーバーにpingや専用のステータス確認URLを呼び出し、正常に応答するかを確認します。応答がない、あるいはエラーが続くサーバーは自動的かつ一時的に振り分け対象から外され、ユーザーに障害が見えないようにし、復旧すれば再び対象に戻されます。確認用URLは、固定で「OK」を返すだけにせず、データベースに接続できるかなど意味のある内容を検査するのが望ましいです。

ロードバランサーとCDNの関係

ロードバランサーは通常同じデータセンター内のサーバー群にトラフィックを分散させるのに対し、CDN(コンテンツデリバリーネットワーク)は世界中に分散したエッジサーバーにトラフィックを分散させます。大規模サービスでは両方を組み合わせるのが一般的で、CDNがまず最寄りのリージョンへリクエストを振り分け、そのリージョン内でロードバランサーがさらにサーバー単位で分散します。

ロードバランシングとオートスケーリングの組み合わせ

クラウド環境ではトラフィックが急増すると、オートスケーリングが新しいサーバーインスタンスを自動的に起動し、ロードバランサーはすぐにそこへトラフィックを振り分け始めます。逆にトラフィックが減れば不要なインスタンスを自動的に減らしてコストを抑えられるため、この2つの技術はクラウドインフラの運用でセットで使われることが多くあります。

Cookieによるスティッキーセッション

IPアドレスをハッシュする代わりに、多くのL7ロードバランサーは最初のリクエストを処理したサーバーを記録するCookieを付与し、そのブラウザからの以降のリクエストを同じサーバーへ送ります。IPハッシュの共有IP問題は避けられますが、利用者が特定のサーバーに結び付くことに変わりはなく、そのサーバーが外れるとセッションが失われます。より堅牢な設計は、セッション情報をデータベースやインメモリキャッシュなどの共有ストアに置き、どのサーバーでも処理できるようにすることです。

TLS終端と本当のクライアントIP

多くのロードバランサーはHTTPSの暗号化処理を自分で行い(TLS終端)、バックエンドには平文または再暗号化した通信を転送します。これにより負荷を肩代わりでき、証明書も一か所で管理できます。バックエンドからは送信元がロードバランサーのアドレスに見えるため、元のアドレスはX-Forwarded-Forなどのヘッダーに付与されるのが一般的で、アプリ側はロードバランサーからのものだけを信頼するよう設定する必要があります。

重み付けとコネクションドレイニング

プール内のサーバーは必ずしも同じ性能ではありません。重みを設定すれば、大きなマシンにより多くのトラフィックを割り当てられます。メンテナンスやデプロイでサーバーを外すときは、コネクションドレイニングにより新規リクエストは送らず、処理中のリクエストは完了させるため、利用者の操作が途中で切れません。数台ずつ順番に更新するローリングアップデートはこの仕組みに依存しています。

基本を超えた分散アルゴリズム

ラウンドロビンと最小接続数は代表的な出発点にすぎず、実際の本番環境ではさらに工夫が加えられることが多くあります。処理能力の高いサーバーにより多くのリクエストを割り当てる重み付きラウンドロビン、直近の応答速度を加味する最小応答時間方式、そしてキャッシュ層で多用され、サーバーが追加・削除されても同じキーがほぼ常に同じサーバーにマッピングされるコンシステントハッシュなどが代表的です。

クラウドネイティブ環境における負荷分散

単体の専用機器だけでなく、現在の負荷分散は複数のレイヤーで同時に行われることが一般的です。クラウド事業者が提供するマネージド型ロードバランサーがアプリケーション全体の手前に立ち、Kubernetesクラスタ内ではIngressコントローラーがトラフィックを分散し、サービスメッシュが内部サービス間の負荷分散を担います。それぞれのレイヤーは、特定のインスタンスに負荷が集中しないようにするという同じ課題を、異なる範囲で解決しています。

ロードバランサーでは解決できないこと

ロードバランサーは仕事を分けますが、遅いアプリケーションを速くはしません。すべてのサーバーが1つの過負荷なデータベースを共有している場合、Webサーバーを増やしてもボトルネックが移るだけで消えません。また、状態をローカルに保持するサーバーの前に置くと、ログインやカートが壊れることもあります。サーバーを増やす前に、監視でボトルネックを特定し、可能ならアプリケーションをステートレスにしましょう。

リクエストの流れを追ってみる

訪問者がサイトを開くと、ブラウザはドメイン名をロードバランサーのアドレスに解決します。ロードバランサーは接続を受け付け、アルゴリズムに従って正常なサーバーを選び、リクエストを転送します。サーバーが作ったレスポンスはロードバランサーを経由して訪問者に戻ります。直近のヘルスチェックに失敗したサーバーはスキップされ、訪問者は障害に気づきません。運用担当者は、サーバーごとの毎秒リクエスト数、エラー率、応答時間を見て、分散が健全かを確認します。

よくある質問

ロードバランサー自体が故障したらどうなりますか?

ロードバランサー自体が単一障害点にならないよう、実際の運用では通常2台以上のロードバランサーをアクティブ・スタンバイ、またはアクティブ・アクティブ構成で稼働させ、一方が停止してももう一方が処理を継続できるようにします。

小規模なサイトにもロードバランシングは必要ですか?

1台のサーバーで十分にトラフィックを処理できるなら、当面は必要ありません。ただしトラフィックが増えて複数台のサーバーが必要になった時点からは、ロードバランサーなしでは分散のしようがないため、必須の要素になります。

ロードバランサーとリバースプロキシは同じものですか?

重なる部分があります。リバースプロキシはサーバーの手前に立ってクライアントのリクエストを転送するもので、多くは負荷分散も行えます。L7ロードバランサーは、分散とヘルスチェックの機能を備えたリバースプロキシのようなものです。L4は内容を読まずに、より低い層で動作します。

どのアルゴリズムを選べばよいですか?

同程度のサーバーで処理時間が短いなら、ラウンドロビンが無難な初期選択です。処理時間のばらつきが大きいなら最小接続数、サーバーの規模が違うなら重み付き、同じサーバーに留めたい場合のみハッシュやCookieを使います。

ロードバランサーは攻撃からも守ってくれますか?

一部のトラフィックを吸収し、バックエンドのアドレスを隠せます。マネージド型にはレート制限やWAFを備えるものもありますが、大規模なDoS攻撃に対する完全な防御はロードバランサー単体ではできません。