Select the product you need help with
設計上の問題 - Winsock と TCP 経由で小さなデータ セグメントを送信する文書番号: 214397 - 対象製品 目次概要
TCP 経由で小さなデータ パケットを送信する必要がある場合、Winsock アプリケーションの設計が特に重要です。遅延確認応答の送受信、Nagle アルゴリズム、および Winsock バッファリングを考慮せずに設計すると、パフォーマンスに大きな影響が出ることがあります。この資料では、2 つのケース スタディを使用して設計上の問題点を説明し、Winsock アプリケーションから小さなデータ パケットを効果的に送信するための一連の推奨事項を説明します。
詳細背景Microsoft TCP スタックはデータ パケットを 1 つ受信すると、200 ミリ秒の遅延タイマを作動させます。最終的に ACK が送信されると、その遅延タイマがリセットされ、次のデータ パケットを受信したときに、新たに 200 ミリ秒の遅延タイマを作動させます。Microsoft TCP スタックでは、インターネット アプリケーションとイントラネット アプリケーションの両方の効率を高めるために、次の条件を使用して、受信したデータ パケットに対して、任意の ACK を送信するタイミングが決定されます。
Winsock では、以下の規則を使用して、アプリケーションに送信完了を示します (完了通知は、ブロッキング呼び出しから返される関数、イベントを通知する関数、または通知関数を呼び出す関数などになる場合があり、これは送信が呼び出される方法によって異なります)。
ケース スタディ 1概要Winsock TCP クライアントが、Winsock TCP サーバーに 10,000 件のレコードを送信し、データベースに格納する必要があるとします。レコードのサイズは、20 〜 100 バイト長まで変化します。アプリケーション ロジックを簡素化するために、設計を以下のようにします。
パフォーマンスクライアントがサーバーに送信できるレコードが 1 秒間に 5 つのみであることがテストで判明します。合計 10,000 件のレコード、つまり、最大で 976 KB のデータ (10,000 * 100 / 1,024) をサーバーに送信するには、30 分以上かかることになります。分析クライアントが TCP_NODELAY オプションを設定しないため、Nagle アルゴリズムによって、TCP スタックは回線上に新たなパケットを送信できるようになる前に、ACK を待つ必要があります。しかし、クライアントでは SO_SNDBUF オプションが 0 に設定されています。そのため、10,000 件の送信呼び出しは個別に送信され、個別に ACK を受信する必要があります。サーバーの TCP スタックでは以下の現象が発生するため、各 ACK が 200 ミリ秒遅延します。
パフォーマンスを向上させる方法この設計には 2 つの問題があります。まず、遅延タイマの問題です。クライアントは 200 ミリ秒以内でサーバーに 2 つのパケットを送信できる必要があります。クライアントは、デフォルトで Nagle アルゴリズムを使用するため、クライアントが使用する必要があるのはデフォルトの Winsock バッファ処理のみであり、SO_SNDBUF を 0 に設定する必要はありません。TCP スタックによって、バッファが結合され、MTU (最大転送ユニット) より大きくなれば、リモート ホストからの ACK を待たずに、すぐにフル サイズのパケットが送信されます。次の問題点は、この設計では、非常に小さなサイズのレコードごとに、送信が 1 つ呼び出される点です。このように小さなサイズを送信することは、あまり効果的ではありません。この場合、開発者は各レコードを 100 バイトに詰め込み、1 回のクライアントからの送信呼び出しの間に 80 件のレコードを一度に送信できます。送信されるレコードの合計数をサーバーに認識させるためには、クライアントは通信を開始する際に後続のレコード数を含む固定サイズのヘッダーを使用することができます。 ケース スタディ 2概要Winsock TCP クライアント アプリケーションで、株価情報サービスを提供している Winsock TCP サーバー アプリケーションとの接続を 2 つ開くとします。最初の接続は、サーバーに銘柄記号を送信するコマンド チャネルとして使用します。2 つ目の接続は、株価情報を受信するデータ チャネルとして使用します。2 つの接続を確立した後、クライアントはコマンド チャネル経由でサーバーに銘柄記号を送信し、データ チャネル経由で株価情報が返信されるのを待ちます。クライアントは、最初の株価情報を受信した後にのみ、次の銘柄記号要求をサーバーに送信します。クライアントとサーバーは、SO_SNDBUF と TCP_NODELAY オプションを設定しません。パフォーマンスクライアントが 1 秒間に取得できる株価情報が 5 つのみであることがテストで判明します。分析このデザインでは、未処理の株価情報要求は一度に 1 つしか許可されません。最初の銘柄記号は、コマンド チャネル (接続) 経由でサーバーに送信され、応答がデータ チャネル (接続) 経由ですぐにサーバーからクライアントに送信されます。その後、クライアントがすぐに 2 つ目の銘柄記号要求を送信すると、送信呼び出しの要求バッファが Winsock カーネル バッファにコピーされるとすぐに、その送信は戻ります。しかし、コマンド チャネル経由の最初の送信の ACK を受信していないため、クライアント TCP スタックはカーネル バッファからすぐに要求を送信できません。サーバー コマンド チャネルで、200 ミリ秒の遅延タイマが経過した後、最初の記号要求に対する ACK がクライアントに戻ってきます。そして、200 ミリ秒の遅延の後、2 つ目の株価情報要求が正常にサーバーに送信されます。2 つ目の銘柄記号に対する株価情報が、データ チャネル経由ですぐに返信されます。これは、この時点でクライアント データ チャネルでの遅延タイマの有効期限が経過したためです。以前の株価情報応答に対する ACK がサーバーによって受信されます (クライアントは 2 つ目の株価情報要求を 200 ミリ秒間送信できないため、クライアント側の遅延タイマが経過するまでの時間を与えられ、サーバーに ACK が送信されます)。その結果、クライアントは 2 つ目の株価情報応答を取得して、新たな株価情報要求を発行できます。これ以降は、同じサイクルで処理が行われることになります。パフォーマンスを向上させる方法この設計では、2 つの接続 (チャネル) を使用する必要はありません。株価情報の要求と応答に対して接続を 1 つだけ使用すると、株価情報要求に対する ACK は株価情報応答に上乗せされ、すぐに戻ることができます。パフォーマンスをさらに向上させるためには、クライアントは複数の株価情報要求をサーバーへの 1 つの送信呼び出しに "多重化" し、サーバーも複数の株式情報応答をクライアントへの 1 つの送信呼び出しに "多重化" することができます。設計上何らかの理由で、単方向チャネルを 2 つ使用する必要がある場合は、以前のパケットに対する ACK を待たずに小さなパケットをすぐに送信できるように、双方が TCP_NODELAY オプションを設定する必要があります。推奨事項これらの 2 つのケース スタディは架空のものですが、最悪の事例を説明するために役立ちます。多数の小さなデータ セグメントの send と recv を含むアプリケーションを設計するときは、以下のガイドラインを考慮する必要があります。
関連情報
遅延確認応答と Nagle アルゴリズムの詳細については、以下の資料を参照してください。
Braden, R.[1989], RFC 1122, Requirements for Internet Hosts--Communication Layers, Internet Engineering Task Force. 関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 214397
(http://support.microsoft.com/kb/214397/EN-US/
)
(最終更新日 2005-07-11) を基に作成したものです。
プロパティ文書番号: 214397 - 最終更新日: 2005年8月22日 - リビジョン: 3.1
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。" | サポート技術情報の翻訳 |










