- Beim Debugging von Latenzproblemen in verteilten Systemen sollte man als Erstes die Einstellung von TCP_NODELAY prüfen
- Der Nagle-Algorithmus wurde 1984 in RFC896 vorgeschlagen und entwickelt, um beim Senden kleiner Pakete den Overhead von TCP-Headern zu reduzieren
- In Kombination mit dem Mechanismus Delayed ACK führt er jedoch dazu, dass die Datenübertragung bis zum Empfang eines ACK verzögert wird, was die Leistung latenzsensitiver Anwendungen verschlechtert
- In modernen Rechenzentrumsumgebungen ist die RTT sehr kurz, und die meisten Systeme senden ohnehin bereits große Nachrichten, sodass der Nutzen des Nagle-Algorithmus fast vollständig verschwunden ist
- Deshalb sollte in modernen verteilten Systemen TCP_NODELAY standardmäßig aktiviert sein; der Nagle-Algorithmus wird nicht mehr benötigt
Hintergrund des Nagle-Algorithmus
- John Nagles RFC896 von 1984 wurde vorgeschlagen, um das Problem eines 4000-%-Overheads bei 1 Byte Nutzdaten gegenüber 40 Byte Header zu lösen, wie es bei kleinen Datenübertragungen wie Tastatureingaben auftrat
- Das damalige Problem war, dass bei jeder einzelnen Tastatureingabe kleine Pakete gesendet wurden und dadurch die Netzwerkeffizienz sank
- Die Lösung bestand darin, das Senden neuer Segmente zu unterbinden, solange frühere Daten noch nicht per ACK bestätigt wurden
- Dieser Ansatz war in der damaligen Netzwerkumgebung effektiv, ist aber für moderne Systeme, in denen Latenz entscheidend ist, ungeeignet
Zusammenspiel von Nagle-Algorithmus und Delayed ACK
- Delayed ACK (RFC813, RFC1122) bedeutet, dass der Empfänger ACKs nicht sofort sendet, sondern sie verzögert, bis Antwortdaten vorliegen oder ein Timer abläuft
- Der Nagle-Algorithmus wartet auf ein ACK und stoppt die Übertragung, während Delayed ACK das ACK hinauszögert; dadurch entsteht ein Deadlock, bei dem beide Seiten aufeinander warten
- John Nagle selbst bezeichnete diese Kombination als eine „schreckliche Kombination“ und wies darauf hin, dass beide Funktionen zwar unabhängig voneinander eingeführt wurden, gemeinsam aber Latenz verursachen
Probleme in modernen Umgebungen
- Innerhalb eines Rechenzentrums liegt die RTT bei etwa 500 μs, selbst innerhalb derselben Region nur bei wenigen Millisekunden
- In solchen Umgebungen führt bereits eine Verzögerung um eine RTT zu Leistungsverlusten
- Zudem senden moderne verteilte Systeme durch TLS, Serialisierung und Protokoll-Overhead ohnehin bereits ausreichend große Nachrichten, sodass das Problem einzelner Byte-Pakete praktisch nicht mehr existiert
- Die Optimierung kleiner Nachrichten wird heute auf Anwendungsebene vorgenommen
Warum TCP_NODELAY nötig ist
- In latenzsensitiven verteilten Systemen wird empfohlen, TCP_NODELAY zu aktivieren und damit den Nagle-Algorithmus zu deaktivieren
- Das ist weder „ineffizient“ noch eine „falsche Konfiguration“, sondern eine Entscheidung, die zu moderner Hardware und heutigen Traffic-Mustern passt
- Der Autor argumentiert, dass TCP_NODELAY der Standard sein sollte
- Zwar kann Code, der bei jedem
write()-Aufruf sendet, dadurch langsamer werden, aber solcher Code sollte grundsätzlich überarbeitet werden
Weitere verwandte Optionen
- Die Option TCP_QUICKACK reduziert ACK-Verzögerungen, ist aber wegen Portabilitätsproblemen und inkonsistentem Verhalten keine grundlegende Lösung
- Das Kernproblem ist, dass der Kernel Daten länger zurückhält, als es die Anwendung beabsichtigt, obwohl sie bei einem
write()-Aufruf sofort gesendet werden sollten
Fazit
- Der Nagle-Algorithmus war eine hervorragende Erfindung, um in früheren Netzwerken die Effizienz zu steigern,
ist jedoch in modernen Hochgeschwindigkeitsnetzwerken und verteilten Systemen eine überholte Funktion, die vielmehr Latenz verursacht
- Daher wird die konsequente Aktivierung von TCP_NODELAY als grundlegendes Prinzip moderner Systemarchitektur vorgeschlagen
Noch keine Kommentare.