The Cable GuyTCP 受信ウィンドウ自動チューニング

Joseph Davies

"TechNet Magazine"** の The Cable Guy の初回の記事へようこそ。TechNet Web サイトのコラムのファンである皆さんは、既にご存じのように、私たちはネットワークに関するあらゆる事柄を取り上げてきました。そしてこれからも毎月この伝統を守っていきます。もしあなたが新しい読者で、過去のコラムをお探しなら、Cable Guy サイトを参照してください。

では、最初のトピック、TCP 受信ウィンドウについて説明します。

TCP 接続を用いたスループットはアプリケーションの送受信、TCP の実装の送受信、および TCP ピア間の伝送パスにより制限される場合があります。このコラムでは、TCP 受信ウィンドウ、TCP 受信ウィンドウが TCP スループットに及ぼす影響、TCP ウィンドウ スケーリングの使用法、および受信データに対して TCP スループットを最適化する Windows Vista™ の新しい受信ウィンドウ自動チューニング機能について説明します。

TCP 受信ウィンドウ

TCP 接続には重要な特徴がいくつもあります。第 1 に、TCP 接続は 2 つのアプリケーション レイヤ プロトコル間での論理ポイント ツー ポイント回線であるということです。TCP は一対多の配信サービスを提供しません。TCP は一対一の配信サービスだけを提供します。

第 2 に、TCP 接続は接続指向であるということです。データが伝送される前に、2 つのアプリケーション レイヤ プロセスが、TCP 接続確立プロセスを使用して、TCP 接続を正式にネゴシエートする必要があります。同様に、TCP 接続は TCP 接続終了プロセスを使用して、ネゴシエート終了後に正式に閉じられます。

第 3 に、TCP 接続で送信された信頼できるデータはシーケンシャルなものであり、受信側から受信確認を受けます。受信確認が受けられない場合は、そのセグメントは再伝送されます。受信側では、複製されたセグメントは破棄され、シーケンシャルでない順番で届いたセグメントは適切な順序で再配置されます。

第 4 に、TCP 接続は全二重であるということです。それぞれの TCP ピアについて、TCP 接続は 2 つの論理パイプから構成されます。送信パイプおよび受信パイプの 2 つです。 TCP ヘッダーには送信データのシーケンス番号および受信データの受信確認 (ACK) の両方が含まれます。

さらに、TCP は受信および送信論理パイプを介して送信されたデータを連続するバイト ストリームとして認識します。それぞれの TCP ヘッダーのシーケンス番号および受信確認番号は、バイトの境界線上で定義されます。TCP はバイト ストリーム内ではレコードまたはメッセージの境界を識別しません。アプリケーション レイヤ プロトコルでは受信するバイト ストリームを適切に解析できる必要があります。

一度に送信できるデータの量を制限し、受信側のフロー制御を提供するために、TCP ピアはウィンドウを使用します。ウィンドウとは、受信側が送信側に送信を許可するバイト ストリーム上のデータの幅のことです。送信側はウィンドウ内に含まれるバイト ストリームのバイトのみを送信できます。ウィンドウは、送信側の送信バイト ストリームおよび受信側の着信バイト ストリームに沿ってスライドします。

指定された論理パイプ (全二重 TCP 接続の 1 方向) の場合、送信側は送信ウィンドウを保持し受信側は受信ウィンドウを保持します。送信中のデータまたは ACK セグメントがない場合、論理パイプの送信および受信ウィンドウは一致します。言い換えれば、送信側が送信を許可した送信バイト ストリーム内のデータの幅は、受信側が受信可能な着信バイト ストリーム内のデータの幅と一致するということです。図 1 はこの送信と受信の関係を示しています。

図 1 送信および受信ウィンドウの一致

図 1** 送信および受信ウィンドウの一致 **(画像を拡大するには、ここをクリックします)

受信ウィンドウのサイズを示すために、TCP ヘッダーには 16 ビットのウィンドウ フィールドが含まれています。受信側がデータを受信すると、受信側は送信側に ACK を送信し、バイトの受信に成功したことを示します。それぞれの ACK 内で、ウィンドウ フィールドは受信ウィンドウ内に残るバイト数を記録します。データが送信され、受信確認され、アプリケーションにより取得されると、送信および受信ウィンドウの両方が右側にスライドします。受信ウィンドウとは、送信側から受信側に受信確認されていないデータをどれだけ送信可能かを制御するウィンドウのことです。

受信ウィンドウ内にはアプリケーションにより取得されていないデータ、および受信はされていても受信確認されていないデータが存在するので、TCP 受信ウィンドウには図 2 が示すように補足的な構造があります。

図 2 TCP 受信ウィンドウのデータの型

図 2** TCP 受信ウィンドウのデータの型 **(画像を拡大するには、ここをクリックします)

最大の受信ウィンドウと現在の受信ウィンドウの間の差に注目してください。最大受信ウィンドウは固定サイズです。現在の受信ウィンドウは可変サイズで、受信側が送信側に送信を許可するデータの残存量に対応しています。現在の受信ウィンドウのサイズは、送信側に送り返される ACK 内で使用されるウィンドウ フィールドの値のことです。また最大受信ウィンドウ サイズと受信され受信確認されていてもアプリケーションにより取得されていないデータ量の差のことでもあります。

TCP 受信ウィンドウおよび TCP スループット

TCP スループットを最適化するには (一般的なエラーのない伝送パスを想定したとして)、送信側は送信側と受信側の間の論理パイプを最大限活用する量のパケットを送信する必要があります。論理パイプの容量は次の数式により計算できます。

Capacity in bits = path bandwidth in bits per second * round-trip time (RTT) in seconds

この容量は帯域幅遅延積 (BDP) と呼ばれています。パイプは太い (広帯域幅) または細い (低帯域幅) または短い (低 RTT) または長い (高 RTT) 場合があります。パイプが太くて長い場合、BDP は最大になります。高 BDP 伝送パスの例には、衛星間通信または大陸間を結ぶ光ファイバ リンクを含むエンタープライズ ワイド エリア ネットワーク (WAN) があります。

高 BDP 伝送の送信側のパフォーマンスの向上

新しい受信ウィンドウ自動チューニング機能は、高 BDP リンク経由のデータ受信のパフォーマンスを向上させますが、送信側のパフォーマンスについてはどうでしょうか。

ネットワークを氾濫させるほどの TCP ピアの送信を防ぐ既存のアルゴリズムは、スロー スタート アルゴリズムおよび輻輳回避アルゴリズムとして知られています。これらのアルゴリズムは、接続上で最初にデータを送信したとき、および失われたセグメントを回復したときに、送信ウィンドウ (送信側が送信可能なセグメント数) を増加させます。

スロー スタート アルゴリズムは、それぞれの受信確認セグメントを受信した場合 (Windows XP および Windows Server 2003 での TCP の場合)、またはそれぞれのセグメントが受信確認された場合 (Windows Vista および Windows Server "Longhorn" での TCP の場合) に 1 つの完全な TCP セグメントにより送信ウィンドウを増加します。輻輳回避アルゴリズムは、受信確認されたデータの完全なウィンドウそれぞれに対して 1 つの完全な TCP セグメントを追加することにより送信ウィンドウを追加します。

これらのアルゴリズムは BDP 値が小さい場合および受信ウィンドウ サイズが比較的小さな場合に適しています。しかし、往復遅延時間が 100ms の高速 WAN リンクに接続されている 2 つのサーバー間でデータをレプリケートする場合のように、受信ウィンドウ サイズが大きく BDP 値も高い TCP 接続の場合、これらのアルゴリズムはこの高速接続環境の帯域を十分に利用できるほど速く送信ウィンドウを増加しません。

このような状況で TCP 接続の帯域をより利用するために、次世代の TCP/IP スタックには Compound TCP (CTCP) が含まれます。CTCP は、大きな受信ウィンドウ サイズおよび高い BDP 値を使用する接続に対して送信ウィンドウをより強制的に増加します。CTCP は、遅延の変動およびパケットロスを監視することにより、これらの種類の接続におけるスループットの最大化を試みます。加えて、CTCP のこれらの動作は、他の TCP 接続に悪影響を及ぼすことはありません。

マイクロソフトでの内部テストでは、往復遅延時間 (RTT) が 50ms の 1Gbps 接続環境での大規模なファイル バックアップに必要な時間が約半分に減少しました。BDP 値がより大きい接続ではさらにパフォーマンスが向上します。CTCP および受信ウィンドウ自動チューニングは、リンク使用率を増加させるために一体となって機能し、その結果 BDP 値が大きい接続でのパフォーマンスが大幅に向上します。

CTCP は、Windows Server "Longhorn" が実行中のコンピュータでは既定で有効になっています。また Windows Vista を実行中のコンピュータでは既定で無効になっています。"netsh interface tcp set global congestionprovider=ctcp" コマンドを使用して CTCP を有効にすることができます。"netsh interface tcp set global congestionprovider=none" コマンドを使用して CTCP を無効にすることができます。

TCP ヘッダー内でのウィンドウ フィールドのサイズは 16 ビットです。これにより TCP ピアは最大 65,535 バイトの受信ウィンドウ サイズに対応します。次の数式を使用して任意の TCP ウィンドウ サイズに対するスループットを概算できます。

Throughput = TCP maximum receive windowsize / RTT

たとえば、65,535 バイトの受信ウィンドウでは、伝送パスの実際の帯域幅に関係なく、RTT が 100ms のパス上では、およそ 1 秒あたり 5.24 メガビット (Mbps) のスループットしか実現できません。今日の高 BDP 伝送パスでは、初期に設計された TCP ウィンドウ サイズは、最大値に設定したとしても、それがスループットのボトルネックになってしまうのです。

TCP ウィンドウ スケーリング

より大きなウィンドウ サイズが高速伝送パスに対応できるようにするために、RFC 1323 (ietf.org/rfc/rfc1323.txt (英語)) が、受信側が 65,535 バイトよりも大きなウィンドウ サイズを提供することを許可するウィンドウ スケーリングを定義します。TCP ウィンドウ スケール オプションにはウィンドウ スケーリング要素があります。ウィンドウ スケーリング要素と TCP ヘッダー内の 16 ビットのウィンドウ フィールドを組み合わせると、受信ウィンドウ サイズを最大約 1 GB に増加できます。ウィンドウ スケール オプションは接続を確立するプロセス中に同期 (SYN) セグメント内にのみ送信されます。両方の TCP ピアについて、受信ウィンドウ サイズに対して、異なるウィンドウ スケーリング要素を使用するように指定できます。TCP ウィンドウ スケーリングで送信側が接続上により多くのデータを送信できるようにすることで、TCP ノードは高 BDP を使用する伝送パスの種類のいくつかをより有効に利用できます。

受信ウィンドウ サイズは TCP スループットにとって重要ですが、最適な TCP スループットを判断するための他の重要な要素は、受信ウィンドウ内に蓄積されたデータをアプリケーションが取得する速度 (アプリケーション取得比率) です。アプリケーションがデータを取得しないと、受信ウィンドウは次第にいっぱいになり、受信側が提供する現在のウィンドウ サイズが小さくなります。極端な例では、最大受信ウィンドウすべてがいっぱいになった場合、受信側が提供するウィンドウ サイズは 0 バイトになります。この場合、受信ウィンドウがクリアされるまで送信側はデータの送信を停止する必要があります。したがって、TCP スループットを最適化するには、接続に対する TCP 受信ウィンドウを、接続する伝送パスの BDP およびアプリケーション取得比率の両方を反映した値に設定する必要があります。

たとえ BDP およびアプリケーション取得比率の両方を正確に判断できたとしても、それらは時間と共に変化します。BDP 比率は伝送パスの輻輳に基づいて変化します。またアプリケーション取得比率はアプリケーションがデータを受信する接続数に基づいて変化します。

Windows XP の受信ウィンドウ

Windows XP (および Windows Server® 2003) での TCP/IP スタックでは、最大受信ウィンドウ サイズに多数の重要な属性があります。第 1 に、デフォルト値は送信インターフェイスのリンク速度に基づいています。実際の値は、TCP 接続を確立する間にネゴシエートされ、最大セグメント サイズ (MSS) まで自動的に調整されます。

第 2 に、最大受信ウィンドウ サイズは手動で設定できます。HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TCPWindowSize および HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Interface\InterfaceGUID\TCPWindowSize のレジストリ値により最大 65,535 バイト (ウィンドウ スケーリングなしの場合) または 1,073,741,823 バイト (ウィンドウ スケーリングありの場合) に設定できます。

第 3 に、最大受信ウィンドウ サイズにウィンドウ スケーリングを使用できます。HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Tcp1323Opts レジストリ値を 1 または 3 に設定することによりウィンドウ スケーリングを有効にできます。既定では、ウィンドウ スケーリングは、受信された SYN セグメントがウィンドウ スケール オプションを含む接続に対してのみ使用されます。

最後に、最大受信ウィンドウ サイズは、接続が開始されたときに SO_RCVBUF Windows Sockets オプションを使用することにより、アプリケーションで指定できます。ウィンドウ スケーリングの場合、アプリケーションは 65,535 バイトより大きいウィンドウ サイズを指定する必要があります。

拡張可能なウィンドウをサポートするにもかかわらず、Windows XP での最大受信ウィンドウ サイズで引き続きスループットを制限できます。その理由は、最大受信ウィンドウ サイズは、アプリケーションによって指定されない限り、すべての TCP 接続に対する固定の最大サイズだからです。これを使用して、いくつかの接続に対してはスループットを増加し、また他の接続に対してはスループットを減少できます。また、TCP 接続に対する固定の最大受信ウィンドウ サイズは、アプリケーション取得比率または伝送パス内の輻輳により変化しません。

Windows Vista の受信ウィンドウ自動チューニング

特に高 BDP を使用する伝送パスに対するスループットを最適化するために、Windows Vista (および "Longhorn" というコード名の Windows Server の次のバージョン) の次世代 TCP/IP スタックは受信ウィンドウ自動チューニングをサポートします。この機能は BDP およびアプリケーション取得比率を測定し、また進行中の伝送パスとアプリケーションに対するウィンドウ サイズを調整することにより、最適な受信ウィンドウ サイズを決定します。

受信ウィンドウ自動チューニングは、既定で TCP ウィンドウ スケーリングを有効にし、16 MB までの最大受信ウィンドウ サイズを許可します。データが接続上で伝送される間、次世代の TCP/IP スタックは接続を監視し、現在の BDP およびアプリケーション取得比率を測定し、スループットを最適化する受信ウィンドウ サイズに調節します。次世代の TCP/IP スタックは TCPWindowSize レジストリ値を使用しなくなりました。

受信ウィンドウ自動チューニングには多くの利点があります。受信ウィンドウ自動チューニングは、接続ごとに最適な受信ウィンドウ サイズを自動的に決定します。Windows XP では、TCPWindowSize レジストリ値がすべての接続に適用されます。アプリケーションは、Windows Sockets オプションを使用して TCP ウィンドウ サイズを指定する必要がなくなりました。また IT 管理者が、特定のコンピュータに対して TCP 受信ウィンドウ サイズを手動で設定する必要がなくなりました。

受信ウィンドウ自動チューニングにより、Windows Vista ベースの TCP ピアは、通常、Windows XP ベースの TCP ピアよりもより大きな受信ウィンドウ サイズを提供できます。これにより他の TCP ピアは、ACK (TCP 輻輳管理による制限) が待機することがなくなり、より多くの TCP データ セグメントを送信するので、Windows Vista ベースの TCP ピアへのパイプを十分に使用することができます。 Web ページまたは電子メールなどの典型的なクライアント ベースのネットワーク トラフィックの場合、Web サーバーまたは電子メール サーバーは、より多くの TCP データをより迅速にクライアント コンピュータに送ることができます。その結果ネットワーク パフォーマンスが全体的に向上します。接続に対する BDP およびアプリケーション取得比率が高いほど、パフォーマンスはより向上します。

ネットワークへの影響については、これまでは TCP データ パケットのストリームは通常より遅い、一定のペースで送信されてきましたが、それがより迅速に送信されることにより、データ伝送中のネットワーク使用率がより大きくなります。Windows XP および Windows Vista ベースのコンピュータの場合、長く、太いパイプで同じデータ伝送が実行されます。伝送されるデータ量は同じです。しかし、Windows Vista ベースのクライアント コンピュータに対するデータ伝送は、より大きな受信ウィンドウ サイズと、サーバーからクライアントへのパイプをサーバーが十分に使用できることによって、より速くなります。

受信ウィンドウ自動チューニングは高 BDP 伝送パスのネットワーク使用率を増加させるので、サービスの品質 (QoS) の使用またはアプリケーション送信比率の調整が、稼働中の伝送パスまたは容量が限界に近づいている伝送パスに対して重要になる場合があります。この予期される必要に対処するため、Windows Vista はグループ ポリシーに基づいた QoS 設定をサポートします。これにより IP アドレスまたは TCP ポート上で送信されるトラフィックに対する調整比率を定義できます。詳細については、ポリシーに基づく QoS に関するリソース (英語) を参照してください。

データが失われる確率の高いネットワークの TCP スループットの増加

データが失われる確率の高いネットワークでは、頻繁なタイム アウトと再伝送のために TCP スループットが極端に減少します。データが失われる確率の高いネットワークの例としては、IEEE 802.11、汎用パケット ラジオ サービス (GPRS)、ユニバーサル モバイル通信システム (UMTS) に基づくような、無線ネットワークがあります。これらはネットワークの状態、シグナル減衰、電磁干渉、コンピュータの設置場所の変更などによりパケットが失われる確率が高くなります。

次世代の TCP/IP スタックは、データが失われる確率の高い環境でのスループットを最適化するために、次の 4 つの RFC をサポートします。

RFC 2582: 新しい Reno アルゴリズムによる TCP 高速回復アルゴリズムの修正

RFC 2001 で定義される高速回復アルゴリズムは、Reno アルゴリズムに基づいています。これによって、高速な再伝送イベントのためにセグメントが再伝送された場合に送信側が送信するデータの量が増加します。Reno アルゴリズムは失われたセグメントが単一の場合適切に機能しますが、失われたセグメントが複数の場合は適切に機能しません。新しい Reno アルゴリズムは、データのウィンドウ内の複数のセグメントが失われ、送信側が部分的な受信確認 (正常に受信したデータの部分だけに対する受信確認) を受信した場合に、送信側が高速回復中に送信比率を増加させることにより、より高速なスループットを提供します。

RFC 2883: TCP の選択的受信確認 (SACK) オプションの拡張

RFC 2018 で定義される SACK は、SACK TCP オプションを使用することにより、受信データの非連続ブロックを 4 つまで受信側が示すことができます。RFC 2883 は、重複したパケットを受信確認するために、SACK TCP オプションで追加フィールドの使用を定義します。これにより送信側は、不必要なセグメントをいつ再伝送したかを判断し、今後の不必要な再伝送を防ぐように自身の動作を調節できます。送信される再伝送が少なくなればなるほど、全体的なスループットが良くなります。

RFC 3517: TCP の損失復旧アルゴリズムに基づく慎重な選択的受信確認

Windows Server 2003 および Windows XP における TCP/IP の現在の実装では、送信先においてどの TCP セグメントが到着していないかを判断するためだけに SACK の情報を使用します。RFC 3517 は、重複する受信確認が受信された場合に損失を復旧するために SACK 情報を使用する方法を定義します。また接続上で SACK が有効な場合は、より古い高速回復アルゴリズムを置き換えます。次世代 TCP/IP スタックは SACK 情報の追跡をピア接続ベースで保持し、送信先において複数のセグメントが受信されないときにより迅速に復旧できるように、入ってくる受信確認だけでなく重複する受信確認も監視します。

RFC 4138: Forward RTO-Recovery (F-RTO): TCP の誤った再伝送タイムアウト検出 (Detecting Spurious Retransmission Timeouts) 用のアルゴリズムおよびストリーム制御伝送プロトコル (SCTP)

RTT の突然の増加により、TCP セグメントの誤った再伝送が引き起こされる場合があります。以前に送信されたセグメントの再伝送タイムアウト (RTO) が次第に期限切れになり、TCP がそれらの再伝送を開始します。データのウィンドウを完全に送信する直前にこの増加が発生した場合、送信側はデータのウィンドウ全体を再伝送します。F-RTO アルゴリズムは、次の動作により TCP セグメントの誤った再伝送を防ぎます。

RTO が複数のセグメントに対して期限切れになると、TCP は最初のセグメントを再伝送します。最初の受信確認が受信されると、TCP は新しいセグメントの送信を開始します (提供されたウィンドウ サイズで可能な場合)。次の受信確認で、タイム アウトしたが再伝送されていない他のセグメントが確認された場合、TCP は、タイムアウトは誤りと判断し、タイム アウトした他のセグメントの再伝送を行いません。

この結果、無線クライアントが 1 つのアクセス ポイントから他のアクセス ポイントに移動した場合など、RTT が突然一時的に増加した環境では、F-RTO が不必要なセグメントの再伝送を防ぎ、より迅速に送信比率を通常に戻します。SACK に基づく損失の復旧および F-RTO の使用は、GPRS リンクを使用する接続に最適です。

Joseph Daviesマイクロソフトのテクニカル ライターとして Windows ネットワークのトピックに関する講義および執筆を 1992 年から行っています。Joseph Davies は、Microsoft Press 向けに本を 5 冊執筆しており、また月間の TechNet Cable Guy コラムの著者でもあります。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; 許可なしに一部または全体を複製することは禁止されています.