ダウンロード速度に影響する内部TCPメカニズム:パート1



内部構造を詳細に表示しないと、プロセスを高速化することはできません。 インターネットの高速化は、基本的なプロトコルであるIPとTCPの理解(および適切な設定)なしでは不可能です。 インターネットの速度に影響を与えるプロトコルの機能を扱いましょう。



IP(インターネットプロトコル)は、ホスト間のルーティングとアドレス指定を提供します。 TCP(Transmission Control Protocol)は、ネットワークが本質的に信頼できないチャネルで確実に動作する抽象化を提供します。



TCP / IPプロトコルは、1974年に発行された「パケットベースのネットワークの通信プロトコル」というタイトルの記事で、Wint CerfとBob Kahnによって提案されました。 RFC 675として登録された元の提案は数回編集されており、1981年にはTCP / IP仕様の4番目のバージョンが2つの異なるRFCとして公開されました。





それ以降、TCPにはいくつかの改良が加えられましたが、そのコアは同じままです。 TCPはすぐに他のプロトコルに取って代わり、現在ではインターネットの機能の主要な要素であるサイト、電子メール、ファイル転送などがその助けを借りて機能しています。



TCPは、ネットワーク接続の必要な抽象化を提供するため、アプリケーションは、失われたデータの再送信、特定の順序でのデータの配信、データの整合性など、さまざまな関連タスクを解決する必要がありません。 TCPストリームで作業する場合、送信されたバイトは受信したバイトと同じであり、同じ順序で送信されることがわかります。 TCPは、データ配信の正確さにより「シャープ」になっていると言えますが、速度ではありません。 この事実は、サイトのパフォーマンスの最適化に関して多くの問題を引き起こします。



HTTP標準では、TCPをトランスポートプロトコルとして使用する必要はありません。 必要に応じて、データグラムソケット(UDP-ユーザーデータグラムプロトコル)またはその他を介してHTTPを送信できます。 しかし実際には、後者の利便性のために、すべてのHTTPトラフィックはTCPを介して送信されます。



したがって、サイトを最適化するには、TCPの内部メカニズムの一部を理解する必要があります。 ほとんどの場合、アプリケーションでTCPソケットを直接操作することはありませんが、アプリケーション設計に関するいくつかの決定によって、アプリケーションが動作するTCPパフォーマンスが決まります。



トリプルハンドシェイク



すべてのTCP接続は、トリプルハンドシェイクで始まります(図1)。 クライアントとサーバーは、アプリケーションデータを交換する前に、パケットシーケンスの初期数と、この接続に関連付けられた他の多くの変数について「同意」する必要があります。 安全のために、シーケンス番号は両側でランダムに選択されます。



SYN



クライアントは乱数Xを選択し、SYNパケットを送信します。SYNパケットには、追加のTCPフラグとオプション値も含まれる場合があります。



SYN ACK



サーバーは、独自の乱数Yを選択し、Xの値に1を追加し、フラグとオプションを追加して、応答を送信します。



質問する



クライアントはXとYの値に1を追加し、ACKパケットを送信してハンドシェイクを完了します。





1.トリプルハンドシェイク。



ハンドシェイクが完了したら、データ交換を開始できます。 クライアントは、ACKパケットの直後にデータパケットを送信できます。サーバーは、ACKパケットがデータの送信を開始するまで待機する必要があります。 このプロセスはすべてのTCP接続で発生し、サイトのパフォーマンスの点で重大な課題を提示します。 結局、すべての新しい接続は、ある程度のネットワーク遅延を意味します。



たとえば、クライアントがニューヨークにあり、サーバーがロンドンにあり、新しいTCP接続を作成している場合、56ミリ秒かかります。 パケットが一方向に移動するのに28ミリ秒、ニューヨークに戻るのに同じ量。 ここでは、チャネル幅は何の役割も果たしません。 TCP接続の作成は「高価」なので、接続を再利用することは、TCPベースのアプリケーションを最適化するための重要な方法です。



TCP Fast Open(TFO)



ページをダウンロードするとは、さまざまなホストから何百ものコンポーネントをダウンロードすることを意味します。 これには、ブラウザが多数の新しいTCP接続を作成する必要があり、それぞれの接続ではハンドシェイクによる遅延が発生します。 言うまでもなく、これは、特にモバイルユーザーにとって、このようなページの読み込み速度を低下させる可能性があります。



TCP Fast Open(TFO)は、SYNパケット内でデータを送信できるため、待ち時間を短縮するメカニズムです。 ただし、制限もあります。特に、SYNパケット内の最大データサイズに制限があります。 さらに、一部のタイプのHTTPリクエストのみがTFOを使用でき、これはCookieを使用するため、再接続に対してのみ機能します。



TFOを使用するには、クライアント、サーバー、およびアプリケーションでこのメカニズムを明示的にサポートする必要があります。 これは、Linuxカーネルバージョン3.7以降と互換性のあるクライアント(Linux、iOS9以降、OSX 10.11以降)を搭載したサーバーで機能します。また、アプリケーション内で対応するソケットフラグを有効にする必要があります。



Googleの専門家は、TFOがHTTPリクエストのネットワーク遅延を15%短縮し、ページの読み込みを平均10%短縮し、場合によっては最大40%短縮できると判断しました。



輻輳制御



1984年の初め、John Neagleはネットワークの状態について説明しました。これは「過負荷崩壊」と呼ばれ、ノード間のチャネル幅が同じではないネットワーク上に形成されます。



ラウンドトリップ遅延(ラウンドトリップパケット通過時間)が最大再送信間隔を超えると、ホストは同じデータグラムのコピーをネットワークに送信し始めます。 これにより、バッファが詰まり、パケットが失われます。 その結果、ホストはパケットを数回送信し、数回試行した後、パケットは宛先に到達します。 これは「オーバーロード崩壊」と呼ばれます。



Nagleは、ノードのチャネル幅が同じであり、バックボーン(高速トランク)が過剰な帯域幅を持っているため、輻輳の崩壊は当時のARPANETNにとって問題ではないことを示しました。 ただし、これは現代のインターネットでは長い間間違っていました。 1986年、ネットワーク内のノードの数が5000を超えたときに、一連の過負荷が発生しました。 場合によっては、これによりネットワーク速度が1000倍に低下し、実際の動作不能になりました。



この問題に対処するために、フロー制御、輻輳制御、輻輳防止などのいくつかのメカニズムがTCPに適用されました。 データを両方向に送信できる速度を決定しました。



フロー制御



フロー制御は、処理できないほど多くのデータが受信者に送信されるのを防ぎます。 これを防ぐために、TCP接続の各側は、着信データに使用可能なバッファースペースのサイズを報告します。 このパラメーターは、「受信ウィンドウ」(rwnd)です。



接続が確立されると、両側はシステムのデフォルトに基づいてrwn値を設定します。 インターネット上の典型的なページを開くことは、サーバーからクライアントに大量のデータを送信することを意味するため、クライアント受信ウィンドウが主な制限事項になります。 ただし、クライアントが大量のデータをサーバーに送信する場合(たとえば、そこにビデオをアップロードする場合)、サーバー受信ウィンドウが制限要因になります。



何らかの理由で受信データストリームに片側が対処できない場合、受信ウィンドウの値が減少したことを報告する必要があります。 受信ウィンドウが0に達すると、受信レベルがアプリケーションレベルでクリアされるまで、データを送信する必要がなくなったことを送信側に通知します。 このシーケンスは各TCP接続で絶えず繰り返されます。各ACKパケットは両側の新しいrwnd値を搬送し、受信側と送信側の機能に応じてデータフローレートを動的に調整できるようにします。





2.受信ウィンドウの値を渡します。



ウィンドウスケーリング(RFC 1323)



元のTCP仕様では、受信ウィンドウの送信値のサイズが16ビットに制限されていました。 これは、受信ウィンドウが2 ^ 16または65,535バイトを超えることはできないため、上からそれを厳しく制限しました。 これは、特に「遅延によるチャネル幅の積」(BDP-帯域幅遅延積)の大きいネットワークでは特に、最適なパフォーマンスには不十分であることがわかっています。



この問題に対処するために、RFC 1323はTCPウィンドウスケーリングオプションを導入しました。これにより、受信ウィンドウのサイズを65,535バイトから1ギガバイトに増やすことができました。 ウィンドウスケーリングパラメータは、トリプルハンドシェイク中に送信され、次のASKパケットで受信ウィンドウの16ビットサイズを左にシフトするビット数を表します。



今日、すべての主要なプラットフォームで受信ウィンドウのスケーリングがデフォルトで有効になっています。 ただし、中間ノード、ルーター、およびファイアウォールは、このパラメーターを上書きすることも、削除することもできます。 接続でチャネル全体を完全に使用できない場合は、受信ウィンドウの値を確認することから始める必要があります。 Linuxプラットフォームでは、ウィンドウスケーリングオプションをチェックして、次のように設定できます。



$> sysctl net.ipv4.tcp_window_scaling $> sysctl -w net.ipv4.tcp_window_scaling=1
      
      





次のパートでは、TCPスロースタートとは何か、データ転送速度を最適化して初期ウィンドウを増やす方法を理解し、TCP / IPスタックを一緒に最適化するためのすべての推奨事項を収集します。



All Articles