2 ポイント 投稿者 GN⁺ 2024-05-10 | 1件のコメント | WhatsAppで共有

TCP_NODELAY設定の重要性

  • 分散システムでレイテンシの問題をデバッグするとき、最初に確認すべきなのは TCP_NODELAY オプションが有効になっているかどうかである
  • 多くの分散システム開発者は、このシンプルなソケットオプションを有効にすることでレイテンシの問題を素早く解決した経験がある
  • これは、デフォルトの動作が適切ではないか、あるいは概念全体が時代遅れになっている可能性を示唆している

Nagleアルゴリズムの背景と問題点

  • 1984年の John Nagle による RFC896 で初めて提案された Nagle アルゴリズムは、TCP ヘッダーのコストをより効率的に償却し、ネットワーク上でより良いスループットを得ることを目的としていた
  • Nagle アルゴリズムは、以前に送信されたデータに対する確認応答が受信されていない場合、新しい TCP セグメントの送信を抑制する方式で動作する
  • しかし、これは delayed ACK と相互作用して問題を引き起こす
    • Nagle アルゴリズムは ACK を受信するまで追加のデータ送信をブロックする一方、delayed ACK は応答の準備ができるまで ACK を遅らせる
    • これはパケットを十分に詰めるには有効だが、レイテンシに敏感なパイプライン型アプリケーションには向いていない

現代のシステムにおけるNagleアルゴリズムの必要性

  • 現代のサーバーは数百マイクロ秒のうちに膨大な量の処理を実行できるため、単一の RTT であってもデータ送信を遅らせることに明確な利点がない場合がある
  • ほとんどの分散データベースやシステムは、1バイトだけのパケットを送ることはない
    • これは、送るべきデータがより多いことに加え、TLS のようなプロトコルのオーバーヘッドや、エンコーディングおよびシリアライズのオーバーヘッドがあるためである
  • 小さなメッセージを送らないことは依然として重要だが、これはアプリケーション層で効果的に処理されている

TCP_NODELAYの使用に関する見解

  • レイテンシに敏感な分散システムを構築する際には、安心して TCP_NODELAY を有効化し(Nagle アルゴリズムを無効化し)てもよい
  • 現代のシステムでは、トラフィックやアプリケーションの mix、ハードウェア性能を考慮すると、Nagle アルゴリズムは不要かもしれない
    • つまり、TCP_NODELAY がデフォルトであるべきだ
    • これは一部の「すべてのバイト書き込み」コードを遅くする可能性はあるが、効率性を重視するなら、いずれにせよそのアプリケーションは修正すべきである

GN⁺の見解

  • Nagle アルゴリズムと delayed ACK の相互作用の問題は、プロトコル設計がいかに難しいかを示す好例である。2つの合理的な機能が意図しない動作を生み出す状況は、システム設計者にとってなじみ深いものだろう。

  • アプリケーション層で小さなメッセージ送信を最適化することは一般的な流れである。効率的なエンコーディングとシリアライズによって不要なオーバーヘッドを最小化することが重要だ。

  • Nagle アルゴリズムの目的がネットワーク帯域幅の最適化だったとすれば、今日ではレイテンシ最小化のほうがより重要な要件である。アプリケーションの応答性がユーザー体験に直結する状況では、不要な遅延は避けるべきだ。

  • ただし、TCP_NODELAY をデフォルトにすることがすべての状況で理想的とは限らない。帯域幅が制限された環境や、転送効率がレイテンシよりはるかに重要なシステムでは、Nagle アルゴリズムを選択的に活用する必要がある。

  • ネットワークプロトコル設計では、多様な要件の間でバランスを取ることが重要である。汎用プロトコルのデフォルト動作を変えるには慎重さが必要だが、アプリケーションの要件に合わせて適切なオプションを選べる柔軟性も必要だと考えられる。

1件のコメント

 
GN⁺ 2024-05-10
Hacker Newsのコメント

要約:

  • Nagleアルゴリズムは書き込みのバッチ化を試みるものであり、ハードウェア、ネットワーク、アプリケーション、ユースケースに関係なく、書き込みのバッチ化の方が優れている場合がある
  • 今日の多くのコンピューティングでは書き込みのバッチ化が使われており、QUICのような新しい高水準プロトコルも書き込みのバッチ化を行うことで、TCPの独立した接続およびエラー処理をユーザー空間へ移している
  • ネットワークが飽和状態になると、NagleアルゴリズムはQUICの修正という形でアプリケーションコードのより深い層に戻ってくるだろう
  • Nagleアルゴリズムは、小さなパケットが原因で1秒あたりのパケット数(PPS)が飽和する場合にも有用である
  • Nagleアルゴリズムは一部のワークロードではうまく機能しないため、エンジニアがソケットを作成する際に明示的に設定すべきである
  • TCP_QUICKACKソケットオプションや/proc/sys/net/ipv4/tcp_delack_min/proc/sys/net/ipv4/tcp_ato_minを使って遅延ACKを無効化できる
  • 帯域幅が限られた世界では、すべてのバイトに対してTCPパケットを送るのは帯域幅の浪費になるため、Nagleアルゴリズムが必要である
  • アプリケーションのソースにアクセスできない場合、TCP_NODELAYを有効にする良い方法はまだない
  • Goのようなモダンな言語はデフォルトでTCP_NODELAYを有効にしているため、この問題は発生しない
  • アプリケーションがTCPスタックに対して対話型シェルであることを伝えられる方法があれば、TCP_NODELAYをデフォルトで無効にしておき、そのアプリケーションに対してのみ有効化できるため、オーバーヘッドを減らせる