2 Punkte von GN⁺ 2024-05-10 | 1 Kommentare | Auf WhatsApp teilen

Die Bedeutung der Einstellung TCP_NODELAY

  • Beim Debuggen von Latenzproblemen in verteilten Systemen sollte man als Erstes prüfen, ob die Option TCP_NODELAY aktiviert ist
  • Viele Entwickler verteilter Systeme haben erlebt, dass sich Latenzprobleme durch das Aktivieren dieser einfachen Socket-Option schnell beheben ließen
  • Das deutet darauf hin, dass das Standardverhalten falsch sein könnte oder das Gesamtkonzept veraltet ist

Hintergrund und Probleme des Nagle-Algorithmus

  • Der Nagle-Algorithmus, erstmals 1984 in John Nagles RFC896 vorgeschlagen, hatte das Ziel, die Kosten der TCP-Header besser zu amortisieren und so einen höheren Durchsatz im Netzwerk zu erreichen
  • Der Nagle-Algorithmus arbeitet, indem er das Senden neuer TCP-Segmente unterdrückt, wenn für zuvor gesendete Daten noch keine Bestätigung eingegangen ist
  • Das führt jedoch in der Interaktion mit delayed ACK zu Problemen
    • Der Nagle-Algorithmus blockiert weitere Datenübertragungen, bis ein ACK empfangen wird, während delayed ACK das ACK verzögert, bis eine Antwort bereitsteht
    • Das ist gut, um Pakete möglichst zu füllen, aber schlecht für latenzsensitive Pipeline-Anwendungen

Braucht man den Nagle-Algorithmus in modernen Systemen noch?

  • Moderne Server können in wenigen hundert Mikrosekunden enorme Mengen an Arbeit erledigen, sodass eine Verzögerung der Datenübertragung selbst um eine einzelne RTT keinen klaren Vorteil mehr bringen muss
  • Die meisten verteilten Datenbanken und Systeme senden keine Ein-Byte-Pakete
    • Das liegt daran, dass mehr Daten übertragen werden und zusätzlich Overhead durch Protokolle wie TLS sowie durch Kodierung und Serialisierung entsteht
  • Es bleibt zwar wichtig, keine kleinen Nachrichten zu senden, doch das wird heute auf der Anwendungsschicht wirksam gehandhabt

Einschätzung zum Einsatz von TCP_NODELAY

  • Beim Aufbau latenzsensitiver verteilter Systeme kann man TCP_NODELAY ohne große Bedenken aktivieren und damit den Nagle-Algorithmus deaktivieren
  • In modernen Systemen könnte der Nagle-Algorithmus unter Berücksichtigung von Traffic, Application-Mix und Hardware-Leistung nicht mehr notwendig sein
    • Anders gesagt sollte TCP_NODELAY der Standardwert sein
    • Das kann zwar manchen Code mit „Byte für Byte schreiben“ verlangsamen, aber wenn Effizienz wichtig ist, müsste diese Anwendung ohnehin überarbeitet werden

Meinung von GN⁺

  • Das Zusammenspiel von Nagle-Algorithmus und delayed ACK ist ein gutes Beispiel dafür, wie schwierig Protokolldesign ist. Situationen, in denen zwei sinnvolle Funktionen unbeabsichtigt problematisches Verhalten erzeugen, dürften Systemdesignern vertraut sein.

  • Das Optimieren der Übertragung kleiner Nachrichten auf der Anwendungsschicht ist ein allgemeiner Trend. Wichtig ist, unnötigen Overhead durch effiziente Kodierung und Serialisierung zu minimieren.

  • Wenn das Ziel des Nagle-Algorithmus die Optimierung der Netzwerkbandbreite war, ist heute die Minimierung der Latenz die wichtigere Anforderung. In Situationen, in denen die Reaktionsfähigkeit einer Anwendung direkt mit der User Experience zusammenhängt, sollte unnötige Verzögerung vermieden werden.

  • Dennoch ist TCP_NODELAY als Standard nicht in jeder Situation ideal. In Umgebungen mit begrenzter Bandbreite oder in Systemen, in denen Übertragungseffizienz deutlich wichtiger ist als Latenz, kann es nötig sein, den Nagle-Algorithmus gezielt einzusetzen.

  • Beim Entwurf von Netzwerkprotokollen ist es wichtig, unterschiedliche Anforderungen gegeneinander abzuwägen. Das Standardverhalten eines universellen Protokolls zu ändern, sollte sorgfältig überlegt werden, zugleich braucht es aber auch die Flexibilität, je nach Anwendungsanforderung die passenden Optionen zu wählen.

1 Kommentare

 
GN⁺ 2024-05-10
Hacker-News-Kommentar

Zusammenfassung:

  • Nagles Algorithmus war ein Versuch, Schreibvorgänge zu bündeln; es gibt Fälle, in denen gebündelte Schreibvorgänge unabhängig von Hardware, Netzwerk, Anwendung oder Anwendungsfall besser sind
  • Ein großer Teil des heutigen Computings nutzt gebündelte Schreibvorgänge, und auch neue High-Level-Protokolle wie QUIC führen Write-Batching durch und verlagern damit die unabhängige Verbindungs- und Fehlerbehandlung von TCP in den User Space
  • Wenn Netzwerke an ihre Auslastungsgrenze kommen, wird Nagles Algorithmus in Form von QUIC-Anpassungen tiefer im Anwendungscode wieder auftauchen
  • Nagles Algorithmus ist auch nützlich, wenn wegen kleiner Pakete die Pakete pro Sekunde (PPS) zum Engpass werden
  • Nagles Algorithmus funktioniert für einige Workloads nicht gut, daher ist es besser, wenn Engineers ihn beim Erstellen eines Sockets explizit setzen müssen
  • Verzögerte ACKs lassen sich mit der Socket-Option TCP_QUICKACK oder über /proc/sys/net/ipv4/tcp_delack_min und /proc/sys/net/ipv4/tcp_ato_min deaktivieren
  • In einer Welt mit begrenzter Bandbreite ist es Bandbreitenverschwendung, TCP-Pakete für jedes einzelne Byte zu senden, daher wird Nagles Algorithmus benötigt
  • Wenn kein Zugriff auf den Anwendungscode besteht, gibt es noch keine gute Möglichkeit, TCP_NODELAY zu aktivieren
  • Moderne Sprachen wie Go aktivieren TCP_NODELAY standardmäßig, daher tritt dieses Problem dort nicht auf
  • Wenn es eine Möglichkeit gäbe, dem TCP-Stack mitzuteilen, dass es sich bei einer Anwendung um eine interaktive Shell handelt, könnte TCP_NODELAY standardmäßig deaktiviert bleiben und nur für diese Anwendung aktiviert werden, was den Overhead reduzieren würde