ページの先頭です
2013年8月6日
SPDY(スピーディと読みます)は、GoogleがWebの表示を高速化するために開発した、新しいプロトコルです。新しいと言っても、今後普及が見込まれるような新技術ではなく、既に実用化され多くの方が日常的に利用しています。
現在ChromeやFirefox、Operaのブラウザを使われている方は、Googleのサービスやtwitterにアクセスしていると、実は全く気付かないうちに、このプロトコルを利用しています。
SPDYは2010年6月にリリースされたChromeのバージョン6安定版からデフォルトで有効になっており、Chrome利用者はこの新技術を3年以上も利用していることになります。
一般のユーザはSPDYを使っているかどうか、どうしたらわかるのでしょうか? Chromeでは、"SPDY Indicator"という便利な拡張機能を提供しています。また同種のツールは、FirefoxやOperaでも同じ名前で提供されています。この"SPDY Indicator"をインストールして、GoogleのサービスサイトやTwitter、Facebook、WordpressといったSPDY対応のWebサイトにアクセスすると、アドレスバーに緑の稲妻アイコンが表示され、ブラウザがSPDYを使っているかどうか一目でわかります。
最近では、ブラウザ側のSPDY対応に合わせて、apache、nginx、JettyといったWebサーバ側でもSPDYがサポートされるようになりました。現在これらのWebサーバをSSLで使っているサイトであれば、誰でも独自にSPDYを利用することが可能です。
これまでSPDYはGoogle独自の仕様でしたが、最近ではIETFで標準化を進める動きが始まりました。2014年春に仕様化を目指すHTTP/2.0では、現在SPDYの仕様をベースとして議論が進んでいます。
本記事では、このSPDYがどういう目的で開発され、どのような仕組みで、どんな効果をもたらしているのか、そして次世代のHTTP/2.0ではどうなるのかを解説します。
現在インターネットで広く利用されているプロトコルは、Webで使われているHTTPです。2013年6月時点で利用されているHTTPのバージョンは1.1であり、これは1999年に仕様化されたものです。
しかし、この10年余でWebの利用状況は劇的に変わりました。Webコンテンツの容量が劇的に増加し、多くのサイトで単に静的にページを表示するだけでなく様々なアニメーションを駆使した動的効果が施されるようになりました。
インフラ的にもCDN(Contents Delivery Network)が普及し、人気サイトでは世界各地のユーザが地理的に最適なサイトにアクセスするよう誘導されていることも珍しくありません。
httparchive.orgの統計によると、2012年10月時点のコンテンツの平均容量は1999年と比べ15倍以上に増加し、1.2MByteを超えています。1ページのWebアクセスでは、平均14のドメイン宛に85のHTTPリクエストが必要になっています。
今後モバイル環境からスマートフォンによるインターネットアクセスが普及すると、このようなリッチコンテンツが更に増えていくものと思われます。
一般的にWeb表示の高速化を目指すアプローチはいくつかあります。GoogleはWebを高速化する効果的な要素を探すため、サーバとクライアント間の回線帯域とRTT(Round Trip Time)を変え、HTTPでWebページを読み込む時間を測定しました。
その結果、ネットワークの回線帯域を増加させても一定の速度を超えると、それ以上ページの読み込み時間が短くならないことがわかりました。一方RTTに関しては、値が小さくなればなるほどページのダウンロード時間が短縮されました。
この比較結果から、Web表示を高速化するには、ネットワーク回線速度を上げるより、RTTを短くする方が効果的であることが見て取れます。これはブラウザによるWebページの読み込み処理が、「DNSによるアドレス解決」、「TCP接続のハンドシェイク」、「HTTPのリクエストとレスポンス」といった3つのステップから構成されており、それぞれの処理時間が回線速度よりもRTTに大きく依存していることに起因しています。
そこでSPDYは、この部分を改善する効果を狙っており、その目的は「Web表示のレイテンシー(待ち時間)を短縮すること」であると定義されています。
SPDYは、Googleが2009年11月にドラフト仕様を公開して、初めて世に知られることになりました。その後SPDYの仕様は、メーリングリストを中心にオープンの場で議論が進められ、現在ではバージョン3がリリースされています。当初SPDYの開発はChromeだけで進められ、SPDYに対応したサーバやサービスは公表されていませんでした。しかし、2011年1月に突然「90%のGoogleサービスでSPDYの対応が完了した」と発表があり、既にSPDYが大規模なサービスで利用されていることが広く知られるようになりました。2011年末にはFirefoxでSPDY対応が開始され、2012年からはChrome以外のクライアントやオープンソースのWebサーバでSPDY対応が急速に進みました。2013年6月時点では、Googleのサービス以外にTwitterやWordPress、Facebookにおいて大規模なSPDY対応が始まっています。
2013年6月時点でChrome、Firefox、Operaの3種類のブラウザにおいて、デスクトップ・モバイル版のSPDY対応が完了しています。特にスマートフォンで用いられるモバイル版のブラウザでは利用できる回線帯域が限られているため、SPDYによる性能向上効果が高く見込まれるものと期待されています。
SPDYは、技術的に「HTTP接続を操作するセッション層の置き換えを行ったもの」と定義できます。これまでHTTP/1.1で利用されてきたメソッドやヘッダといったHTTPのセマンティクスを変更するものではありません。SPDYは、Webコンテンツを取得するセッションの手順を新しく定義し直したものです。その目的は、ハードウェア性能・ソフトウェア技術・ネットワーク環境の進歩に合わせてWeb表示の高速化を図ることです。その上、現実的な普及ができるよう既存環境との共存も十分考慮されています。
Webサイト管理者の視点から、SPDYの利用には以下3つの利点があります。
先述した通り、SPDYの大きな特徴は、TLSと組み合わせることで既存環境との併用が可能であることです。この方法は、Googleが提案したTLSのNPN(Next Protocol Negotiation)拡張を利用することで実現しています。この拡張仕様は、現在IETFにドラフト仕様が提出されており、既にオープンソースのOpenSSLに実装されている機能です。
NPN拡張によってどうやってプロトコルが選択されるのか、手順の概略は以下の通りです。まずTLSの最初のハンドシェイク(ClientHello)時にクライアントがNPN拡張を利用できることを通知します。サーバは返答時(ServerHello)に同じ拡張フィールドを使って利用可能なプロトコルリストをクライアントに返します。続けてTLSの証明書チェックや暗号化設定の手続きが終わると、最後にクライアントからサーバ宛に次に利用するプロトコル名を通知します(NextProtocol)。その際クライアントは、自身が使えるもののうちサーバが提示したリストから1番初めのエントリを選択します。このやりとりが終わると、初めてSPDYの利用がサーバ・クライアント間で開始されます。
このNPN拡張は、SPDYの利用に限るものではありません。他のプロトコルでもサーバとクライアントの間で利用可能プロトコル名を認識していれば使うことが可能です。またプロトコル名は通常[spdy/3,spdy/2,http/1.1]のようにバージョン番号を含めて記述されています。このため、どちらかが最新バージョンに対応していない場合でも両者が古いバージョンを選択し、SPDYを利用することができます。
他にもTLSを利用すると「通信経路の暗号化によるセキュリティが確保できる」、「FireWallや透過プロキシなどによるデータ変更の影響を排除できる」といった利点も得られます。
なお現在仕様検討中のHTTP/2.0では、NPNの手順を改良したALPN(Application Layer Protocol Negotiation)仕様を利用することが採用されています。
SPDYではzlibを使いHTTPヘッダ情報を圧縮しています。このため冗長で長いヘッダを利用するような場合、送信データ量を小さくすることができます。Googleの測定によると、ヘッダを圧縮すると最初のHTTPリクエストで平均10%~35%程度のサイズ縮小効果が見込めると報告されています。特にモバイル通信ではクライアントからサーバへのアップロード帯域が小さく設定されている場合が多く、ヘッダ圧縮がより効果的になると見られています。
しかし2012年9月にセキュリティ研究者によって、暗号化された通信上でも圧縮されたデータを解読する手法が公開されました。彼らが開発したCRIMEというツールを利用し、TLSで暗号化された通信上でクッキーなどのヘッダ情報を取得することに成功しました。そのため2012年10月時点では、SPDY利用時でもブラウザ側でヘッダを圧縮しない措置が取られています。現在、仕様策定中のHTTP/2.0では、この脆弱性に対応した新たなヘッダ圧縮手法の導入が検討されています。
SPDYで送受信するデータは、バイナリー形式でやり取りします。そのデータはフレームという単位で構成されており、コントロールフレームとデータフレームの2種類で構成されています。コントロールフレームは、HTTPリクエスト・レスポンスヘッダの送受信などのSPDY通信制御情報のやり取りに使います。データフレームは、HTTPリクエストボディとレスポンスボディのデータを送受信する時に利用します。コントロールフレームは、バージョン3では9つのタイプに分かれています。このうちSYN_STREAMとSYN_REPLYの2つのコントロールフレームはストリームの生成を行う重要なフレームです。SYN_STREAMフレームは32bit単位のフィールドを使って図-3.1に示します。各フィールドと、それによって生成されるストリームの役割を説明します。
SPDYのストリームは、従来のHTTPのリクエストとレスポンスで行われる一連のやり取りを一つのセッションとして管理する単位です。各ストリームは生成時にユニークなIDを割り当てられ、1つのSPDY接続上に同時に複数のストリームをオープンしたまま通信することができます。この仕組みによって多重化通信を実現しています。またクライアント・サーバ側からそれぞれ任意のタイミングで独自にSYN_STREAMを発信できるため、SPDY上で全2重通信が行えます。ストリームIDは、サーバ側のオープンでは偶数、クライアント側からは奇数を割り当てるようにしてIDが衝突しないようにしています。これはクライアントからのリクエストでないとセッションを開始することができない、従来のHTTPと大きく機能が異なる点です。SPDYはこの仕組みを利用して独自のサーバプッシュ機能(後述)を実現しています。
各ストリームは、生成時に0から7の優先度を割り当てることができます。これによってストリームの送受信の順番と関係なく、送信側が処理ポリシーを明示的に受信側に適応させることができます。例えば、HTML、CSS、JavaScriptといったデータ種類に応じて優先度を付与すると、コンテンツの送信順番に関係なくデータ種類に応じたクライアント側の処理に最適な順番でデータ受信が行えます。
圧縮されたヘッダは、SYN_STREAM/SYN_REPLYの最後に付与されます。この方法以外にも、別のコントロールフレームを使ってヘッダ情報のやり取りすることが可能です。SPDYで送受信するヘッダは、キー・バリュー形式で記載されています。この形式であれば扱うデータはHTTPヘッダに限定されません。サーバとクライアントの間で規定していれば汎用的にデータの送受信が可能であるため、今後SPDYがWebの用途以外にも利用されることが期待されています。2013年1月にLINEがSPDYを利用していると公表しています。LINEの動作仕様の詳細は不明ですが、これはブラウザ以外の専用アプリにおけるSPDYの応用例だと思われます。
実際のWebコンテンツやクライアントからPOSTされた入力データなどのボディ部分は、データフレームを使って送受信を行います。データフレームには、対応するストリームIDが付与されています。SPDYではデータフレームの容量によって効率的に送受信が行えるようにウィンドウサイズの制御ができるWINDOW_UPDATEのコントロールフレームが定義されています。
全てのストリームを送信し終わるとGOAWAYのコントロールフレームを使ってSPDYを終了します。これまで解説した仕組みについて、一連の単純なSPDYのストリームフローを例に表すと図1のようなります。
先述の通りSPDYは全2重通信が可能であるため、サーバ側からクライアントに対してストリームを生成することができます。この仕組みを利用して、サーバ側からクライアントにコンテンツを送り込む機能を「サーバプッシュ」と呼びます。サーバプッシュは、クライアントからHTTPリクエストが送信される前にレスポンスデータをクライアントに送付して、あらかじめクライアントにキャッシュを生成させておく機能です。サーバプッシュの仕組みを表す簡単なフローを図2に示します。サーバがクライアントからHTTPリクエストのSYN_STREAMを受け取ると、次にリクエストが来ると予想されるレスポンスとデータ(主に画像)を先にクライアントに送付します。
クライアントは、サーバからプッシュされたデータのURLとコンテンツをローカルにキャッシュします。サーバはプッシュするデータを送り終わると最初のリクエストに対するレスポンスデータをクライアントに返答します。クライアントはレスポンスを受け取りますが、既にキャッシュされているコンテンツに対して新たにリクエストを行わないため、直ちにWebページのレンダリングが開始されます。サーバプッシュは、サーバからレスポンスデータを一方的に送りつけてキャッシュを生成させる手法です。
しかしサーバプッシュを使うには、コンテンツに応じて次に何がリクエストされるかサーバ側があらかじめ把握しておくロジックが必要です。また一度にあまり大量のサーバプッシュを行うとクライアントがキャッシュ生成で過負荷になる可能性もあります。サーバプッシュは、従来行われていたイメージ画像をHTML内にインライン展開するチューニング方法と同程度の高速化を実現しますが、サーバプッシュはプッシュされたページと別のページでもキャッシュの再利用ができる点でインライン化よりメリットがあります。
SPDYは全2重多重化通信を実現できるので、クライアントとサーバ間で1つTCPの接続を継続して使い続ける仕様となっています。このため、新たなTCP接続を生成する必要がなく、TCPハンドシェイクやスロースタートのオーバヘッドを回避できるメリットがあります。従来のブラウザは、サーバに対して複数接続を行うことで並列度を上げ、高速化を行う必要がありました。
しかしサーバの過負荷を避けるために、同時接続数は最大6つに制限されています。そのためコンテンツ中に多数の画像データへのリンクが存在していると、最大同時接続数の制限で画像のダウンロードが待たされるものが出てきました。
一方、SPDYでは同時にいくつもストリームを生成できるため、そのような制限はありません。(サーバ側で同時ストリーム数を明示的に制限している場合もあります。Googleのサービスでは同時ストリーム数を100に制限しています。)HTTPでは画像のダウンロードが6ファイル単位でHTML中の記述順序に従って処理されていますが、SPDYの場合ではファイルの順番や最大同時接続数に縛られずにダウンロードが行われます。SPDYはリソースのダウンロード待ちをできるだけ少なくして、より効率的にWebページの読み込みを行う仕組みを目指しています。
さらにSPDYを使うと、1つのクライアントからサーバにTCP接続する絶対数が少なくなり、「サーバのリソースに優しい」といったメリットもあります。特にChromeでは、ワイルドカードのSSL証明書を利用して同じIP群のDNSを登録していると、アクセスするサイト名が異なってもSPDY接続が共有されるようになっています。SPDYはTCP接続のオーバヘッドをできるだけ少なくし、ブラウザ通信の効率化を最大限にする工夫がなされています。
SPDYを導入しても、必ずしも全てのサイトが無条件に高速化されるわけではありません。SPDYの技術的な特徴を活かせる構成では性能向上を期待することができますが、既存の環境をそのままでSPDYを適応すると、逆効果になるケースも考えられます。そのような構成を3つほど例示します。
ではWeb表示の高速化を目指すSPDYは、いったいどの程度、表示を高速化できるのでしょうか?これまでGoogleを始めとする、いくつかのベンチマーク結果が公表されています。当初実験環境では、ページ表示速度が2倍に向上するといった結果が公表されていましたが、その後実サイトを模擬した疑似的なモバイル環境では、2~3割の向上に留まるといったレポートが公開されています。一方、CDN環境では数パーセント程度の改善しか見られないとの報告もあります。また非SSLのサイトとの比較では、SPDY化による恩恵よりもSSL化の遅延の方が大きいといったことも言われています。
筆者がベンチマークを行ったところ、SPDYによって平均で12%~15%程度、読み込み時間が改善されました。ただし、ベンチマークを繰り返すと劇的に読み込みが早くなる場合もあれば、SSLより遅くなる場合もあります。これらの結果を見ると、単純にSPDYを導入すればWebサイトの読み込み速度が劇的に変化する、というわけではないのは確かです。そのため日頃からサイトのパフォーマンス測定を継続して行い、SPDY導入後もその効果が何に依存するのかといった運用ノウハウを蓄積することが求められます。
先に述べた通りSPDYは、IETFでHTTP/2.0仕様のベースとして採用され、現在精力的に仕様化に向けて議論が続けられています。本節は2013年6月末時点での状況を元にHTTP/2.0の仕様化の概要を説明します。
HTTP/2.0の仕様化は、10数年ぶりのHTTPを大改訂する作業です。HTTP/2.0を開始するにあたり、3つの提案仕様からSPDYが採用され、SPDYをベースとした仕様化の作業が始まりました。SPDYをベースにするといっても、仕様がそのまま使われるわけではありません。先に述べたSPDYの目的や特徴は、大部分がHTTP/2.0に引き継がれていますが、仕組みに関しては大きく見直しが入っています。
幾つか変更点の概略を書くと、
等が挙げられます。
特にフレームの構造は、図-3.1(SPDY/3のSYN_STREAMフレーム)と図-3.2(HTTP/2.0のHEADERSフレーム)を比較してみると、違いは明らかです。白抜きのSPDY/3の18バイトのフレームヘッダ部分が、HTTP/2.0では8バイトに縮小され、バージョン番号やスロット等の余分なフィールドがなくなっています。10種類用意されていたSPDY/3のフレームタイプは、HTTP/2.0では9つになり、その役割に大きな変更が加えられています。
2013年夏に実装仕様のドラフトを作成し、初めて相互接続試験を行う予定です。2014年春には仕様化完了を目指します。
執筆者プロフィール
大津 繁樹(おおつ しげき)
IIJ プロダクト本部 戦略的開発部
1999年4月、IIJ入社。SIエンジニア・コンサルタントやサービスエンジニアを経て、現在HTML5、Kinectハック、Node.jsなどのアプリケーションの新技術検証・評価を中心に行っている。
ページの終わりです