4.4. TCP_NODELAY および小さいバッファー書き込み

TCP (Transmission Control Protocol) の簡単な説明にあるように、デフォルトで TCP は Nagle のアルゴリズムを使用して小さな送信パケットを収集し、すべてを一度に送信します。レイテンシーに悪影響を与える可能性があります。

手順4.3 TCP_NODELAY および TCP_CORK を使用したネットワークレイテンシーの改善

  1. 送信されるすべてのパケットでレイテンシーが短いアプリケーションでは、TCP_NODELAYが有効なソケットで実行する必要があります。これは、sockets API を使用して setsockopt コマンドで有効にできます。
    # int one = 1;
    
    # setsockopt(descriptor, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
    
  2. これを効果的に使用するには、アプリケーションは、小規模で論理的に関連するバッファー書き込みを実行しないようにする必要があります。TCP_NODELAY が有効であるため、これらの小さい書き込みにより、TCP はこの複数のバッファーを個別のパケットとして送信するため、全体的なパフォーマンスが低下する可能性があります。
    アプリケーションに論理的に関連し、1 つのパケットとして送信された複数のバッファーがある場合は、メモリーに連続するパケットを構築し、TCP_NODELAY で設定したソケット上の TCP に論理パケットを送信することが可能です。
    I/O ベクトルを作成し、TCP_NODELAY で設定したソケットで writev を使用してカーネルに渡します。
  3. 別の方法としては TCP_CORK を使用する方法があります。これは 、アプリケーションがコークを削除するのを TCP に指示してからパケットを送信するよう指示します。このコマンドにより、受信するバッファーが既存のバッファーに追加されます。これにより、アプリケーションはカーネル領域にパケットを構築できます。これは、レイヤーの抽象化を提供する異なるライブラリーを使用する場合は必要です。TCP_CORK を有効にするには、setsockopt ソケット API を使用して 1 値に設定します (これは「ソケットの修正」と呼ばれます)。
    # int one = 1;
    
    # setsockopt(descriptor, SOL_TCP, TCP_CORK, &one, sizeof(one));
    
  4. アプリケーションの各種コンポーネントで論理パケットがカーネルにビルドされたら、コードを削除するように TCP に指示します。TCP は、アプリケーションからのパケットをこれ以上待たずに、累積された論理パケットをすぐに送信します。
    # int zero = 0;
    
    # setsockopt(descriptor, SOL_TCP, TCP_CORK, &zero, sizeof(zero));
    
関連する man ページ

詳細は、以下の man ページは本セクションに記載の情報に関連しています。

  • tcp(7)
  • setsockopt(3p)
  • setsockopt(2)