【テクニカル・上級編】HTTP/1.1におけるドメインシャーディングの設計概念 – HTTPプロトコル・通信規格実践ガイド

ドメインシャーディングという「副作用」と、HTTP/1.1の終焉が教える現代の最適化

インフラエンジニアの夜明け前、ふと統計データやパケットキャプチャを眺めていると、HTTP/1.1の時代に設計された「ドメインシャーディング(Domain Sharding)」という、ある種の狂気とも言える最適化手法の残滓に遭遇することがある。

かつてWebサイトが重いのは、ブラウザの「ドメインごとの同時接続数制限(通常6本)」がボトルネックだったからだ。現代の我々から見れば、なぜわざわざDNSルックアップを増やし、TCPのコネクションを浪費してまでリソースを分散させたのかと問い詰めたくなるが、当時のエンジニアたちは、限られたプロトコルスタックの中で必死にRTT(往復遅延時間)を削り取ろうとしていたのだ。

今日は、この「ドメインシャーディング」という名のドーピングが、現代の高速通信インフラにおいてどのような負債となり、そして次世代プロトコルへの移行でどう解消されたのかを、カーネルレベルの挙動から紐解いていこう。

—

1. ドメインシャーディングの呪縛:DNSとTLSのコスト

ドメインシャーディングの本質は、`static.example.com`、`assets1.example.com`といったサブドメインを乱立させ、ブラウザのコネクション制限を論理的に回避することにある。しかし、この手法は以下の3つのインフラ的コストを増大させた。

  • DNSルックアップのオーバーヘッド: 異なるドメインごとにDNSクエリが発行される。キャッシュヒットしない場合、UDPによる再帰的検索が走り、初回のRTTが数ミリ秒から数十ミリ秒単位で食いつぶされる。
  • TCPスロースタートの浪費: 各ドメインへの接続ごとにTCPの3ウェイハンドシェイクが必要となる。コネクションごとに初期ウィンドウ(initcwnd)がリセットされるため、帯域幅を最大化するまでの「助走期間」が何度も発生する。
  • TLSハンドシェイクの多重負荷: 各サブドメインに対して個別にTLS証明書を検証し、鍵交換を行う必要がある。これはCPU負荷だけでなく、ハンドシェイクの往復回数(RTT)を劇的に増やす要因だ。

2. パケットレベルで見る「コネクション」の分断

Linuxカーネルのネットワークスタックを追うと、シャーディングされた環境では、`ss -nt`コマンドで確認できるTCPソケットの数が激増する様子が観察できる。

現在のTCPコネクションの輻輳制御状態を確認
ドメインシャーディング環境では、多数のソケットが ‘cwnd’(輻輳ウィンドウ)を
小さな値から個別に立ち上げ直している様子が見える
ss -nti ‘sport = :443’

TCPバッファ(`tcp_rmem`, `tcp_wmem`)のチューニングにおいて、コネクションが分断されていると、一つ一つのストリームに対してカーネルは個別にメモリを割り当てる。これは、グローバルな帯域の利用効率を低下させ、パケットロス発生時の再送処理において、単一の大きなコネクションであれば得られたはずの「TCPの学習効果」を阻害する。

3. なぜHTTP/2以降では「悪手」なのか

HTTP/2が登場した際、ドメインシャーディングは即座に「時代遅れ」と断じられた。HTTP/2の多重化(Multiplexing)は、一つのTCPコネクション上で複数のリクエストを並行処理する。つまり、「ドメインを分ける必要性」が完全に消滅したのだ。

HTTP/2における最適化の指標

もしあなたが今、HTTP/2やHTTP/3(QUIC)環境でドメインシャーディングを維持しているなら、それは直ちに止めるべきだ。以下の理由でパフォーマンスが悪化する。

1. HPACKヘッダー圧縮の断絶: HTTP/2のヘッダー圧縮はコネクション単位で機能する。ドメインが異なれば、ヘッダーのインデックス・テーブルを共有できず、圧縮効率が劇的に下がる。
2. 優先順位付け(Prioritization)の無効化: ブラウザは単一のコネクション内であれば、重要なリソース(CSS/JS)を先に送るようストリームを制御できるが、ドメインが別れるとこの制御が不可能になる。

4. 現場のアーキテクトが今すぐ実行すべきチェックリスト

もしレガシーな環境からモダンなインフラへ移行する過渡期にあるなら、以下のチューニングを検討してほしい。

  • TCP初期ウィンドウの拡大:

カーネルパラメータを調整し、最初のパケット送信で送れるデータ量を増やす。

# sysctl.conf
# initcwnd を 10 に設定して、スロースタートの回数を減らす
net.ipv4.tcp_slow_start_after_idle = 0

  • TLSセッション再開(Session Resumption)の強制:

TLS 1.3の0-RTTや、TLSセッションチケットを活用し、サブドメイン間のハンドシェイクコストを極限まで圧縮する。

  • ALPN (Application-Layer Protocol Negotiation) の最適化:

Nginx等のリバースプロキシで、HTTP/2およびHTTP/3へのプロトコル優先度を明示的に設定する。

Nginx 設定例:HTTP/2の恩恵を最大化する
listen 443 ssl http2;
推奨されるプロトコル設定
ssl_protocols TLSv1.2 TLSv1.3;
HTTP/2 ヘッダー圧縮のチューニング
http2_max_field_size 4k;

結論:ネットワークを「一本化」する勇気

ドメインシャーディングは、HTTP/1.1という「直列的なプロトコル」に対する、当時のエンジニアたちの精一杯のアンチテーゼだった。しかし、現代のネットワークアーキテクチャにおいては、「コネクションの集約」こそが最大の最適化である。

DNSルックアップを減らし、TLSハンドシェイクを最小化し、TCPストリームを一本に絞る。そうすることで初めて、我々は現代の広帯域かつ高レイテンシなインターネット環境で、真の「即時表示」を実現できる。

かつてのベストプラクティスは、往々にして技術的負債の隠れ蓑になる。今一度、あなたのアーキテクチャが、過去の亡霊に縛られていないかを確認してほしい。パケットは常に、最も効率的でシンプルな道を求めているのだから。

コメント

タイトルとURLをコピーしました