ELB の 3 種類はなぜ 3 種類あるのか - ALB・NLB・CLB が分かれた設計判断の裏側
ALB、NLB、CLB (Classic) の 3 種類のロードバランサーがなぜ統合されずに併存しているのかを、OSI 参照モデルのレイヤー、パフォーマンス特性、歴史的経緯から解説します。
Classic Load Balancer - ELB の原点
2009 年に登場した Elastic Load Balancing (現在の Classic Load Balancer) は、AWS 初のロードバランサーサービスでした。CLB は L4 (TCP) と L7 (HTTP/HTTPS) の両方のトラフィックを処理できる汎用的なロードバランサーとして設計されました。しかし、この「何でもできる」設計が、後に問題を生みます。L4 と L7 のロードバランシングは、技術的に根本的に異なる処理です。L4 はパケットの送信元・送信先 IP アドレスとポート番号だけを見てルーティングします。パケットの中身 (HTTP ヘッダーやボディ) は一切解析しません。L7 は HTTP リクエストの内容 (URL パス、ホストヘッダー、Cookie など) を解析してルーティングします。この 2 つの処理を 1 つのサービスで提供すると、L4 の処理に L7 のオーバーヘッドが影響し、L7 の機能拡張が L4 の安定性に影響するというトレードオフが生じます。CLB はこの制約により、L7 の高度なルーティング (パスベースルーティング、ホストベースルーティング) を実装できませんでした。
ALB の誕生 - L7 に特化した設計
2016 年に登場した Application Load Balancer (ALB) は、L7 (HTTP/HTTPS) に完全に特化したロードバランサーです。CLB では不可能だったパスベースルーティング (/api/* は API サーバーへ、/static/* は静的ファイルサーバーへ)、ホストベースルーティング (api.example.com と www.example.com を異なるターゲットグループへ)、HTTP ヘッダーや Cookie に基づくルーティングが可能になりました。ALB が L7 に特化したことで実現した重要な機能が、WebSocket のネイティブサポートと HTTP/2 のサポートです。CLB は WebSocket を正しく処理できず、HTTP/2 もサポートしていませんでした。ALB はさらに、AWS WAF との統合、Cognito 認証の組み込み、Lambda 関数をターゲットとして直接呼び出す機能など、アプリケーション層に密接に関わる機能を次々と追加しています。これらの機能は L7 の HTTP リクエストを解析できるからこそ実現可能であり、L4 のロードバランサーでは原理的に不可能です。ALB の料金は、LCU (Load Balancer Capacity Unit) という独自の単位で計算されます。LCU は新規接続数、アクティブ接続数、処理データ量、ルール評価数の 4 つの指標の最大値で決まります。
NLB の誕生 - L4 の極限性能を追求
2017 年に登場した Network Load Balancer (NLB) は、L4 (TCP/UDP/TLS) に特化し、極限のパフォーマンスを追求したロードバランサーです。NLB は毎秒数百万のリクエストを処理でき、レイテンシは数十マイクロ秒と、ALB の数ミリ秒と比較して桁違いに低いです。この性能差は、NLB がパケットの中身を一切解析しないことから生まれます。NLB はフロー (送信元 IP + ポート、送信先 IP + ポートの組み合わせ) 単位でルーティングを決定し、以降のパケットは同じターゲットに転送します。HTTP ヘッダーの解析、Cookie の読み取り、URL パスの評価といった処理が一切ないため、オーバーヘッドが極めて小さいのです。NLB のもう一つの重要な特徴は、静的 IP アドレスのサポートです。ALB は IP アドレスが動的に変わるため、DNS 名でしかアクセスできません。NLB は各 AZ に固定の IP アドレス (Elastic IP を割り当て可能) を持つため、ファイアウォールの IP ホワイトリストに登録できます。金融機関や通信事業者のように、接続先の IP アドレスを固定する必要がある環境では NLB が必須です。
なぜ 1 つに統合しないのか
「ALB と NLB を 1 つのサービスに統合すればいいのでは」という疑問は自然ですが、統合しない理由は技術的に明確です。L4 と L7 のロードバランシングは、処理のパイプラインが根本的に異なります。L7 はすべてのパケットを受信し、HTTP リクエストとして再構成し、ヘッダーを解析し、ルーティングルールを評価し、必要に応じてヘッダーを書き換えてからターゲットに転送します。この処理はメモリと CPU を消費します。L4 はパケットのヘッダー (IP + TCP/UDP) だけを見て転送先を決定し、パケットの中身には触れません。極端な場合、NLB はカーネルのネットワークスタックをバイパスして、NIC (ネットワークインターフェースカード) レベルでパケットを転送できます。この 2 つの処理を 1 つのサービスに統合すると、L4 の性能が L7 の処理パイプラインに引きずられて劣化します。AWS の設計哲学「目的特化型サービス」は、この種のトレードオフを避けるために、機能を分離して最適化する方針です。
選択の判断基準
3 種類の ELB の選択は、ワークロードの特性で決まります。HTTP/HTTPS のトラフィックを処理し、パスベースやホストベースのルーティングが必要なら ALB です。Web アプリケーション、REST API、マイクロサービスのほとんどは ALB が最適です。TCP/UDP のトラフィックを処理し、極限のパフォーマンスや静的 IP が必要なら NLB です。ゲームサーバー、IoT デバイスからの接続、金融取引システム、gRPC (HTTP/2 ベースだが L4 で十分なケース) は NLB が適しています。CLB は新規構築では使用すべきではありません。AWS は CLB から ALB または NLB への移行を推奨しており、CLB にしかない機能はほぼありません。唯一の例外は、EC2-Classic ネットワーク (2022 年に廃止) を使用していた古い環境です。ALB と NLB を組み合わせるパターンもあります。NLB の背後に ALB を配置すれば、NLB の静的 IP と ALB の L7 ルーティングを両立できます。AWS PrivateLink は NLB を前提としているため、PrivateLink でサービスを公開しつつ L7 ルーティングも必要な場合にこの構成が使われます。ロードバランサーの設計パターンを体系的に学ぶには、専門書籍 (Amazon)が参考になります。