こんにちは!技術メディア編集長の私です。
日頃からWebサイトをブラウジングしていて、「なんだか最近のWebサイトは、画像も動画も盛りだくさんなのに、ものすごく表示が速いな」と感じたことはありませんか?その裏側では、目に見えないところで通信技術のドラマが日々繰り広げられています。
その立役者の一つが、今回の主役である「HTTP/2」、そしてその中でもいぶし銀の働きを見せる「HPACK(エイチパック)によるヘッダー圧縮」です。
「ヘッダー圧縮? なんか難しそう……」と思ったそこのあなた!大丈夫です。一歩ずつ、身近な例えから優しく紐解いていきましょう。
—
そもそもHTTP/2の「ヘッダー」って何をしているの?
Webブラウザ(クライアント)がサーバーに「このページを見せて!」とリクエストを送るとき、あるいはサーバーが「はい、どうぞ!」と返すとき、必ず「HTTPヘッダー」というお供のデータがついてきます。
このヘッダーの中身は、いわば「荷物の伝票」です。
- 「私はこんなブラウザを使っていますよ(User-Agent)」
- 「スマホ用の画面サイズに対応しています(Accept)」
- 「このクッキーを保持しています(Cookie)」
……などなど、通信のたびに毎回たくさんの情報がやり取りされています。
実は、この伝票、毎回ほとんど同じ内容が書かれているんです。想像してみてください。毎日同じ宛先に、同じ差出人の名前と住所が書かれた手紙を何通も送っているようなものです。「毎回全部書かなくても、お互いにわかってるんだから省略しようよ!」と思いますよね。
その願いを叶えたのが、HTTP/2のヘッダー圧縮技術、通称「HPACK」です。
—
郵便の宛先を「番号」でやり取りする仕組み
HPACKがやっていることを、現実世界の郵便配達に例えてみましょう。
あなたが毎日、特定の会社(サーバー)に書類を送るとします。最初のうちは、封筒の表に長ーい住所や部署名、担当者名を一文字残らず書かなければいけません。これが通常のHTTP通信です。
しかし、HPACKを使うと、こんな魔法が使えます。
1. 初回(静的テーブルの活用):
よく使われる決まり文句(例:`method: GET` や `path: /` など)は、あらかじめ「辞書(静的テーブル)」に登録されています。だから、文字そのものを送る代わりに「辞書の何番!」と小さな番号で送ることができます。
2. 2回目以降(動的テーブルの学習):
ここからが今回の本題、「動的テーブル(Dynamic Table)」の出番です!
動ってどういうこと?:通信中に賢く学習する仕組み
動的テーブルとは、いわば「今まさにやり取りしている相手と共有する、その場限りのメモ帳」です。
例えば、あなたがサーバーと通信を始めたとしましょう。
その中で、以下のような長〜いカスタムヘッダーを送信したとします。
`X-User-Session-Token: abc123xyz789-very-long-secret-token`
これを毎回、一文字ずつ送っていたらネットワークの帯域がもったいないですよね。
そこで、HTTP/2の通信(コネクション)の裏側で、クライアントとサーバーはこう考えます。
> 「ねえ、今の `X-User-Session-Token: abc123xyz789-very-long-secret-token` って長かったよね。これからこれを『メモ帳の62番』として覚えようか!」
お互いの脳内(正確にはメモリ上)のメモ帳に、この組み合わせが書き込まれます。
すると、次に同じユーザー情報付きのリクエストを送るときはどうなるでしょう?
もう長い文字列を送る必要はありません。ただ「62番!」とだけ送れば、サーバー側は「あぁ、あの長いトークンね」と瞬時に理解してくれるのです。
これが、動的テーブルの仕組みです。通信をすればするほど、お互いの「よく使うフレーズ」を学習し、どんどん通信が軽くなっていくわけです。
—
メモリの暴走を防げ!「動的テーブルのサイズ制限」というブレーキ
「じゃあ、使えば使うほどメモ帳にどんどん記憶させていけば、無限に速くなるんじゃないの?」
鋭いですね!しかし、世の中そんなに甘くありません。ここでインフラエンジニアの腕の見せ所、「メモリ管理」の問題が登場します。
お互いのメモ帳(動的テーブル)は、無制限に大きくできるわけではありません。なぜなら、サーバーやスマホ、パソコンのメモリは有限だからです。もし、世界中からアクセスが来る巨大なWebサーバーが、何百万ものクライアントのカスタムヘッダーを無限に記憶し続けたらどうなるでしょうか?
そう、サーバーのメモリがパンクしてクラッシュしてしまいます。
そのため、HPACKの仕様では、この動的テーブルに対してしっかりと「ここまでしかメモリを使っちゃダメですよ」という上限(Maximum Size)が厳密に決められています。
実務での設定やパラメータのイメージ
実際にNginxやApacheなどのWebサーバー、あるいはGoやNode.jsなどのプログラミング言語でHTTP/2を扱う際、この動的テーブルの最大サイズ(一般的には `SETTINGS_HEADER_TABLE_SIZE` と呼ばれます)を調整することができます。
設定ファイルのイメージを覗いてみましょう。
NginxにおけるHTTP/2設定のイメージ(※実際のディレクティブとは異なる場合があります)
http {
# HPACKの動的テーブルが消費する最大メモリサイズを指定
# デフォルトは通常 4096オクテット(4KB)ですが、環境に応じて調整します
http2_max_requests 1000;
# サーバー側からクライアントに対して「動的テーブルはこのサイズまでにしてね」と通知します
# メモリがカツカツの組込み機器などでは小さくし、リッチなサーバーでは大きめに取ることもあります
}
もし、新しいヘッダーを覚えてメモ帳がいっぱいになってしまったらどうなるでしょうか?
郵便配達のメモ帳と同じで、「一番古くて、しばらく使われていない古いメモ」から順にシュレッダーにかけられて(削除されて)新しいメモに書き換えられます。
この「追加と削除のバランス」をリアルタイムで完璧にコントロールしながら、パケットを極限までスリム化しているのがHPACKの動的テーブルなのです。
—
まとめ:見えない優しさが支える快適なインターネット
いかがでしたでしょうか?
HTTP/2のヘッダー圧縮(HPACK)における動的テーブルは、一見すると小難しい仕様に見えますが、本質は「お互いのやり取りを記憶し、次に活かす賢いコミュニケーション術」です。
- 静的テーブル:最初から決まっている共通の辞書
- 動的テーブル:通信しながらお互いに学習していくその場限りのメモ帳
- サイズ制限:メモリのパンクを防ぐための大切なブレーキ
私たちが普段、ストレスなくサクサクとWebサイトを見られるのは、こうしたプロトコルの裏側でエンジニアたちが知恵を絞り、メモリの隅々まで効率よく使ってデータを圧縮してくれているおかげなんですね。
ネットワークやプロトコルの世界は、こうした「人間関係のちょっとした工夫」に似たロジックが詰まっていて、知れば知るほど面白くなってきます。
ぜひ、今日からブラウザの開発者ツール(F12キーなど)を開いて、ネットワークタブの「Protocol: h2」やヘッダーのやり取りを眺めてみてください。きっと、これまでとは違った景色が見えてくるはずですよ!
それでは、また次回の技術の深掘りでお会いしましょう。インフラ・ネットワークスペシャリストの私でした!
コメント