ロードバランサー完全解説:数百万トラフィックを支えるシステムの秘密
あなたのアプリがバズった瞬間を想像してみてください。数分以内に数百万ものユーザーが一気に流れ込んでくる。もしそのトラフィックがたった1台のサーバーに集中したら、システムは瞬時にダウンし、売上もユーザー体験も底を打つことになるでしょう。
しかし、大手テクノロジープラットフォームはそのような惨事をほぼ起こしません。数百万トラフィックを捌く秘密は、高価なスーパーコンピューターを持つことではなく、ロードバランサー(負荷分散装置) という「指揮者」がデータの流れを静かに制御しているからです。
この記事では、ロードバランサーのすべてを体系的に解説します。コアとなる分散アルゴリズム、レイヤー4・レイヤー7での振り分け方法、そして大規模なトラフィック急増を乗り越えるための自動スケーリングまで、設計思想を整理してこの重要な仕組みを完全に理解しましょう。
第1部:分散アルゴリズム
ロードバランサー(LB)が「このリクエストは誰に渡す?」を決めるロジック、つまり負荷分散アルゴリズムから見ていきましょう。
代表的な3つのアルゴリズムを、シンプルなものから順に紹介します。
🔄 ラウンドロビン(Round Robin)
トランプのカードを配るイメージです。1枚目はサーバーA、2枚目はサーバーB、3枚目はサーバーC、そしてまたAに戻る、という順番で機械的に振り分けます。
- メリット:非常にシンプルで公平
- デメリット:LBはサーバーの実際の状態を把握できません。サーバーAが過負荷状態で、サーバーBはアイドル状態であっても、それを考慮せずにリクエストを割り当てます。
⚖️ リーストコネクション(Least Connections)
ラウンドロビンよりも賢いアルゴリズムです。LBは各サーバーのアクティブな接続数を追跡し、新しいリクエストが来たときに最も空いているサーバーに割り当てます。処理時間が長いリクエストと短いリクエストが混在するシステムで特に効果的です。
📌 IPハッシュ(IP Hash)
ユーザーのIPアドレスをハッシュ関数で計算して、割り当てるサーバーを決定します。これにより、特定のユーザーは常に同じサーバーに接続されます(そのサーバーが死んでいない限り)。ログインセッションやショッピングカートの維持に役立ちます。
⚡ 発展版:重み付きラウンドロビン(Weighted Round Robin)
現実のシステムではサーバーの性能が異なることが多いです。たとえばサーバーAが最新の高性能マシンで、B・CがA の半分の処理能力しかない古い仮想マシンだとします。
単純なラウンドロビンでは、AはB・Cが過負荷になっている間、余裕を持て余します。この問題を解決するために**重み(Weight)**という概念が加えられました。
サーバーA(高性能):重み = 2
サーバーB(旧式) :重み = 1
サーバーC(旧式) :重み = 1
4つのリクエストが来た場合、A → A → B → C の順で割り当てられます。サーバーAのキャパシティを最大限に活かしつつ、B・Cも過負荷にならないように調整できます。同様の考え方で重み付きリーストコネクション(Weighted Least Connections) も存在します。
第2部:ロードバランサーの種類(レイヤー4 vs レイヤー7)
LBがどのような「情報」を使ってリクエストを振り分けるかによって、2つの種類に分かれます(OSIモデルに基づく分類)。
レイヤー4 ロードバランサー(トランスポート層)
郵便局の仕分け担当者に例えられます。非常に素早く処理しますが、封筒の表(IPアドレスとポート番号)しか見ません。中身のテキストは一切読みません。
レイヤー7 ロードバランサー(アプリケーション層)
取締役秘書に例えられます。封筒を開封して中身を読む権限を持ちます。HTTPを理解し、ユーザーがどのURL(パス)にアクセスしているか、Cookieを持っているか、スマートフォンかPCかも把握できます。ただし、「読む」処理が増える分、レイヤー4より若干処理速度が低下します。
実践例:パスベースのルーティング
ECサイトに動画レビュー機能を追加し、動画専用の高性能サーバークラスターを用意したとします。/video を含むパスへのリクエストをそのクラスターに振り向けたい場合、レイヤー7のロードバランサーが必須です。
レイヤー4はIPアドレスとポートしか見えないため、/video というパスを読み取ることができません。レイヤー7はHTTPを理解しているため、URL全体(パスを含む)を読み取って適切なサーバーに転送できます。
この技術を パスベースルーティング(Path-based Routing) と呼びます。/video、/payment、/user-profile など複数のパスを、それぞれ専用のサーバークラスターに振り分けることができます。
第3部:ヘルスチェック(Health Check)
高可用性(High Availability)を維持するための重要な仕組みを見ていきましょう。
LBが3台のサーバー(A、B、C)に均等に負荷を分散しているとします。突然サーバーBのハードディスクが故障したり、アプリケーションがフリーズしたりします。LBがこれを認識できなければ、ユーザーのリクエストをサーバーBに送り続け、ユーザーは502 Bad GatewayやGateway Timeoutのエラーに遭遇することになります。
TCP チェック(レイヤー4)
LBがサーバーのポートに「ノック」し、TCPコネクションが受け付けられるかを確認します。サーバーが応答すれば「正常」とみなされます。
- 課題:ポートは開いていても、内部のWebアプリがフリーズして白画面を返す状況は検出できません。
HTTP チェック(レイヤー7)
最も信頼性の高い方法です。LBが実際のHTTPリクエストを送り(例:/health_status へのGETリクエスト)、サーバーが 200 OK を返すかどうかを確認します。タイムアウトや 500 Internal Server Error の場合は「Unhealthy」と判定します。
「Unhealthy」と判定されたサーバーはキューから自動的に除外され、新しいリクエストは送られなくなります。その後もバックグラウンドで定期的にヘルスチェックを続け、3回連続で200 OKが返ってきた時点でキューに復帰させます(設定値は調整可能)。
⚠️ 単一障害点(SPOF)問題
「サーバーを保護するロードバランサー自体が壊れたら?」という疑問が浮かびます。LBが1台だけだと、そのLBが落ちた瞬間に全サービスが停止します。これが単一障害点(Single Point of Failure = SPOF) です。
大規模システムでは、LBは必ずペアで運用されます(通常はActive-Passive構成)。2台のLBが共通の仮想IP(Virtual IP) を共有します。クライアントはこの仮想IPにアクセスします。ActiveなLBが機能している間、PassiveなLBは監視します。ActiveなLBが死んだ瞬間、PassiveなLBが即座に仮想IPを引き継ぎ(通常1秒未満で)サービスを継続します。
第4部:SSL終端(SSL Termination)
現代のほぼすべてのウェブサイトはHTTPS(暗号化通信)を使用しています。HTTPSの復号化はCPUに大きな負荷をかけます。
暗号化されたHTTPSデータを復号する処理を「どこで行うか」という設計判断が重要です。
🔓 SSL終端(SSL Termination)
LBがSSL証明書を持ち、クライアントからのHTTPSリクエストを復号します。その後、平文のHTTPとして内部のサーバーに転送します。
🔒 SSLパススルー(SSL Passthrough)
LBは「盲目の運搬者」として機能します。暗号化されたパケットをそのまま内部サーバーに転送し、サーバー自身が復号を行います。
比較表
| 観点 | 🔓 SSL終端 | 🔒 SSLパススルー |
|---|---|---|
| サーバー負荷軽減 | ✅ 良好(サーバーはアプリ処理に集中) | ❌ 各サーバーが自前で復号(CPU消費大) |
| レイヤー7機能 | ✅ 利用可能(URLやCookieで振り分け可能) | ❌ 不可(パケット内容が読めないのでレイヤー4のみ) |
| 証明書管理 | ✅ 容易(LBに1枚だけインストール) | ❌ 各サーバーが個別に管理が必要 |
| 内部セキュリティ | ⚠️ やや低い(LB〜サーバー間はHTTP) | ✅ 最高(エンドツーエンド暗号化) |
実際の現場では、SSL終端が最も多く採用されています。証明書管理が楽で、レイヤー7機能を活かせるためです。エンドツーエンド暗号化が必要な銀行・医療などの厳格なセキュリティ要件があるシステムではSSLパススルーが選ばれます。
応用:SSLブリッジング(SSL Bridging / Re-encryption)
「パスで振り分けたいが、内部転送も暗号化したい」という相反する要件がある場合はどうするか?
解決策1:SSLブリッジング
LBはレイヤー7で動作し、クライアントからのパケットを一度復号してパス(/transfer など)を読み取ります。転送先を決定後、直ちに新しいHTTPSセッションとして再暗号化して内部サーバーに送ります。LBが一瞬だけデータにアクセスできますが、経路上のデータは常に暗号化されています。
解決策2:サブドメイン分割
パスではなくサブドメインで分けます(例:info.example.com と pay.example.com)。LBはレイヤー4で動作し、SNI(Server Name Indication) という仕組みを使ってドメイン名を封筒の表から読み取り、pay.example.com のトラフィックをそのままSSLパススルーで決済クラスターに転送します。
第5部:スティッキーセッション(Sticky Session)
オンラインショッピング中を想像してください。3台のサーバー(A、B、C)がラウンドロビンで動いています。
- ログインに成功。この時サーバーAが担当し、ログイン情報はA上に記録される
- カートに商品を追加。今度はLBがリクエストをサーバーBに転送
- サーバーBはあなたのことを知りません(ログイン情報はサーバーAにあるため)→ ログアウトされる
これはHTTPがステートレス(stateless)プロトコルであることが原因です。IPハッシュで解決できますが、同一IPを共有する会社のオフィスからのアクセスが多い場合、特定のサーバーに集中してしまう問題があります。
🍪 Cookie を使ったセッション固定
レイヤー7のLBはCookieを読み書きできるため、スティッキーセッション(Sticky Sessions / Session Affinity) という仕組みを実装できます。
動作の流れ:
- 初回アクセス:ブラウザにはまだCookieがないため、LBはラウンドロビンでサーバーAを選択
-
バッジを発行:LBはレスポンスに
SERVERID=Server_AというCookieを付与してブラウザに返す -
次回以降:ブラウザは自動的に
SERVERID=Server_AのCookieを送信。LBはそれを読んで、常にサーバーAに転送する
IPハッシュと異なり、IPアドレスに依存せず確実にセッションを維持できます。
⚠️ サーバーダウン時の問題と解決策
スティッキーセッションの致命的な弱点:サーバーAが突然ダウンした場合、Aに「固定」されていたユーザーはセッションをすべて失い、ログアウトされてしまいます。
現代的な解決策:外部セッションストア(Redis/Memcached)
セッション情報を各サーバーのメモリに保持するのではなく、外部の集中ストレージ(Redisなど) に保存します。
どのサーバーに振り分けられても → Redisからセッション情報を取得 → シームレスに継続
サーバーAがダウンしても、サーバーBはRedisから同じセッション情報を取得し、ユーザーはログアウトされることなくショッピングを続けられます。
第6部:オートスケーリング(Auto-scaling)
ブラックフライデーなどで通常の100倍ものアクセスが来た場合、既存の3台のサーバーはすべてフル稼働し、まもなく限界に達します。このとき「援軍(新しいサーバー)を自動的に呼ぶ」仕組みが必要です。
クラウド環境(AWS、Google Cloudなど)では、LBは直接サーバーを増設するのではなく、 オートスケーリンググループ(Auto Scaling Group) と連携して動作します。
スケールアウト(Scale Out)のフロー
1. メトリクスの監視
- サーバーのCPU・RAM使用率(例:平均CPU使用率が70%超)
- LBが報告するリクエスト数(例:1サーバーあたり1000 req/秒を超過)
2. 新サーバーの追加
① オートスケーリンググループが新しいサーバーを起動
② アプリケーションが起動
③ 新サーバーのIPをLBに登録
④ LBがヘルスチェックを実施(200 OKを確認)
⑤ 確認後、トラフィックを振り分け開始
ポイント:LBは ヘルスチェックが通過するまで 新サーバーにトラフィックを送りません。これにより、まだ準備できていないサーバーへのリクエストを防ぎます。
スケールイン(Scale In)と安全な終了
トラフィックが落ち着きCPU使用率が30%以下になったら、コスト削減のためサーバーを削減します。しかし「電源を急に抜く」ようなことはできません。処理中のリクエストがある可能性があるからです。
LBは コネクションドレイニング(Connection Draining / Deregistration Delay) という仕組みを使います:
- 対象サーバーを「終了処理中」とマーク
- 新しいリクエストの転送を停止
- 既存のリクエストが完了するまで待機(通常30〜300秒)
- サーバーが完全にアイドルになってからシャットダウン
第7部:グローバルルーティング(GSLB)
これまでの内容で、1つのデータセンター内での大規模トラフィック対応は完璧になりました。
しかし、物理的な制約として 光の速さ の問題があります。サーバーが米国にあれば、いくら高性能なサーバーとLBを揃えても、日本やアジアのユーザーは地球の裏側からアクセスするため高遅延(ピン高)が発生します。
GSLB(グローバルサーバーロードバランシング)
この地理的な問題を解決するのがGSLBであり、その核心技術はDNSです。
DNSはインターネットの「電話帳サービス」のようなものです。ブラウザが example.com にアクセスしようとすると、まずDNSに「このドメインのIPアドレスは?」と問い合わせます。
スマートDNSシステム(Amazon Route 53やCloudflareなど)は次のように動作します:
- 位置特定(Geolocation):問い合わせ元のIPアドレスから、ユーザーの所在地を判定(例:このIPは東京)
- 最適データセンターの選択:米国と東京にデータセンターがある場合
- ジオルーティング:日本ユーザーには東京DCのIPを返す(遅延約5ms)、米国ユーザーには米国DCのIPを返す(遅延約10ms)
このスマートなDNSサーバーのおかげで、誰もが地球の裏側にアクセスせずに済みます。
また、大手テクノロジー企業は Anycast(エニーキャスト) という技術も活用しています。単一のIPアドレスを世界中でアドバタイズし、ルーターが自動的に最も近い物理ノードにパケットを転送します。Cloudflare、Google Public DNS、Fastlyなどがこの技術を使っています。
まとめ:ロードバランサーの全体像
7つの重要なトピックを経由して、ロードバランサーの全貌を理解しました。
| # | トピック | 主なポイント |
|---|---|---|
| 1 | アルゴリズム | ラウンドロビン、リーストコネクション、IPハッシュ、重み付き |
| 2 | OSIレイヤー分類 | レイヤー4(高速・IP/Port基準) vs レイヤー7(高機能・HTTP/URL基準) |
| 3 | ヘルスチェック | 自動障害検知 & SPOF対策(Active-Passive構成) |
| 4 | SSL | SSL終端(サーバー負荷軽減) vs SSLパススルー(エンドツーエンド暗号化) |
| 5 | スティッキーセッション | CookieによるセッションPin & 外部ストア(Redis)での対応 |
| 6 | オートスケーリング | Auto Scaling Groupとの連携 & コネクションドレイニング |
| 7 | グローバルルーティング(GSLB) | DNSジオルーティングで地理的遅延を解消 |
最終課題:配車アプリのロードバランサー設計
ここまで学んだ知識を総合して考えてみましょう。
GrabやUberのような配車アプリのロードバランサーを設計する場合:
- ユーザーは常に移動中で、座標データをリアルタイムで更新する必要がある
- 4G/5G接続が頻繁に切断・再接続する
- ピーク時間(朝・夕の通勤時間帯)と閑散時間の差が激しい
この7つのツールのうち、どれが最も「生命線」になるでしょうか?ぜひコメントで教えてください!