Latenz in TCP/IP-over-Ethernet-Netzwerken

Latenz in TCP/IP-over-Ethernet-Netzwerken

Welche Ressourcen (Bücher, Webseiten usw.) würden Sie empfehlen, die:

  • Erklären Sie die Ursachen der Latenz in TCP/IP-over-Ethernet-Netzwerken.
  • erwähnen Sie Tools zum Suchen nach Dingen, die Latenz verursachen (z. B. bestimmte Einträge in netstat -s);
  • Schlagen Sie Möglichkeiten vor, den Linux-TCP-Stack zu optimieren, um die TCP-Latenz zu reduzieren (Nagle, Socket-Puffer usw.).

Das Nächstliegende, das mir bekannt ist, istdieses Dokument, aber es ist ziemlich kurz.

Alternativ können Sie die obigen Fragen auch gerne direkt beantworten.

bearbeitenUm es klarzustellen: Die Frage bezieht sich nicht nur auf „abnormale“ Latenz, sondern auf Latenz im Allgemeinen. Außerdem geht es speziell um TCP/IP-over-Ethernet und nicht um andere Protokolle (selbst wenn diese bessere Latenzeigenschaften aufweisen).

Antwort1

In Bezug auf die Latenzeinstellungen des Kernels fällt eines besonders auf:

echo 1 > /proc/sys/net/ipv4/tcp_low_latency

Von demDokumentation:

Wenn diese Option gesetzt ist, trifft der TCP-Stack Entscheidungen, die eine geringere Latenz einem höheren Durchsatz vorziehen. Standardmäßig ist diese Option nicht gesetzt, was bedeutet, dass ein höherer Durchsatz bevorzugt wird. Ein Beispiel für eine Anwendung, bei der diese Vorgabe geändert werden sollte, wäre ein Beowulf-Rechnercluster. Standard: 0

Sie können in Ihrer Anwendung auch den Nagle-Algorithmus (der die TCP-Ausgabe bis zur maximalen Segmentgröße puffert) mit etwas wie: deaktivieren.

#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <linux/tcp.h>

int optval = 1;
int mysock;

void main() {
    void errmsg(char *msg) {perror(msg);exit(1);}

    if((mysock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        errmsg("setsock failed");
    }

    if((setsockopt(mysock, SOL_SOCKET, TCP_NODELAY, &optval, sizeof(optval))) < 0) {
        errmsg("setsock failed");
    }

    /* Some more code here ... */

    close(mysock);
}

Das „Gegenteil“ dieser Option ist TCP_CORK, wodurch Pakete „neu genagelt“ werden. Beachten Sie jedoch, dass TCP_NODELAYmöglicherweise nicht immer das erwartete Ergebnis liefert und in manchen Fällen die Leistung beeinträchtigen kann. Wenn Sie beispielsweise Massendaten senden, möchten Sie den Durchsatz pro Paket maximieren TCP_CORK. Setzen Sie daher . Wenn Sie eine Anwendung haben, die sofortige Interaktivität erfordert (oder bei der die Antwort viel größer ist als die Anfrage, wodurch der Overhead aufgehoben wird), verwenden Sie TCP _NODELAY. Außerdem ist dieses Verhalten Linux-spezifisch und BSD ist wahrscheinlich anders, daherVorbehaltsadministrator.

Stellen Sie sicher, dass Sie Ihre Anwendung und Infrastruktur gründlich testen.

Antwort2

Meiner Erfahrung nach ist die häufigste Ursache fürabnormalLatenz in ansonsten gesunden Hochgeschwindigkeitsnetzwerken sind TCP Windowing (RFC1323, Abschnitt 2) Fehler, mit einem eng verwandten zweiten Fehler im Zusammenhang mit TCP Delayed Acks (RFC1122 Abschnitt 4.2.3.2). Beide Methoden sind Erweiterungen von TCP zur besseren Handhabung von Hochgeschwindigkeitsnetzwerken. Wenn sie ausfallen, sinken die Geschwindigkeiten auf ein sehr niedriges Niveau. Fehler in diesen Fällen betreffen große Übertragungen (denken Sie an Backup-Streams), wohingegen extrem transaktionaler kleiner Datenverkehr (durchschnittliche Datenübertragung liegt unter der MTU-Größe und es gibt VIEL Hin- und Her) davon weniger betroffen ist.

Auch hier habe ich die größten Probleme mit diesen beiden Problemen gesehen, wenn zwei verschiedene TCP/IP-Stacks miteinander kommunizieren. Wie etwa Windows/Linux, 2.4-Linux/2.6-Linux, Windows/NetWare, Linux/BSD. Gleiches zu Gleichem funktioniert sehr, sehr gut. Microsoft hat den Windows TCP/IP-Stack in Server 2008 neu geschrieben, was zu Linux-Interoperabilitätsproblemen führte, die es bei Server 2003 nicht gab (ich glaube, diese wurden behoben, bin mir da aber nicht 100 % sicher).

Meinungsverschiedenheiten über die genaue Methode der verzögerten oder selektiven Bestätigung können zu Fällen wie diesem führen:

192.168.128.5 -> 192.168.128.20: 1500b Nutzlast, SEQ 1562
192.168.128.5 -> 192.168.128.20: 1500b Nutzlast, SEQ 9524
[200ms vergehen]
192.168.128.20 -> 192.168.128.5: ACK 1562
192.168.128.5 -> 192.168.128.20: 1500b Nutzlast, SEQ 12025
192.168.128.5 -> 192.168.128.20: 1500b Nutzlast, SEQ 13824
[200ms vergehen]
192.168.128.20 -> 192.168.128.5: ACK 12025

Der Durchsatz sinkt aufgrund der 200-ms-Timeouts (Windows stellt seinen Timer für verzögerte Bestätigungen standardmäßig auf 200 ms ein). In diesem Fall konnten beide Seiten der Konversation die verzögerte TCP-Bestätigung nicht verarbeiten.

TCP-Windowing-Fehler sind schwerer zu erkennen, da ihre Auswirkungen weniger offensichtlich sein können. In extremen Fällen schlägt Windowing vollständig fehl und Sie erhalten Paket->Bestätigung->Paket->Bestätigung->Paket->Bestätigung, was bei der Übertragung von Daten, die deutlich größer als etwa 10 KB sind, sehr langsam ist und alleGrundlatenzauf der Verbindung. Der Modus, der schwieriger zu erkennen ist, liegt vor, wenn beide Seiten ihre Fenstergröße ständig neu aushandeln und eine Seite (der Absender) die Aushandlung nicht einhält, sodass einige Pakete verarbeitet werden müssen, bevor die Daten weiter übermittelt werden können. Diese Art von Fehler wird in Wireshark-Traces durch rot blinkende Lichter angezeigt, äußert sich aber in einem niedrigeren Durchsatz als erwartet.


Wie ich bereits erwähnt habe, sind die oben genannten Probleme häufig bei großen Übertragungen ein Problem. Datenverkehr wie Streaming-Videos oder Backup-Streams können davon betroffen sein, ebenso wie das einfache Herunterladen sehr großer Dateien (wie ISO-Dateien von Linux-Distributionen). TCP Windowing wurde als Methode entwickelt, um grundlegende Latenzprobleme zu umgehen, da es die Pipelining-Funktion von Daten ermöglicht. Sie müssen nicht auf die Roundtrip-Zeit für jedes gesendete Paket warten, sondern können einfach einen großen Block senden und auf eine einzelne ACK warten, bevor Sie weitere senden.

Allerdings profitieren bestimmte Netzwerkmuster nicht von diesen Workarounds. Hochtransaktionale, kleine Transfers, wie sie von Datenbanken generiert werden, leiden am meisten unternormalLatenz auf der Leitung. Wenn die RTT hoch ist, leiden diese Workloads stark, während große Streaming-Workloads viel weniger leiden.

Antwort3

Auf diese Frage gibt es viele Antworten.

Denken Sie daran, wie TCP funktioniert. Der Client sendet SYN, der Server antwortet mit SYN/ACK und der Client antwortet mit ACK. Sobald der Server das ACK erhalten hat, kann er Daten senden. Das bedeutet, dass Sie die doppelte Roundtrip-Zeit (RTT) abwarten müssen, um das erste Bit sinnvoller Daten zu senden. Wenn Sie 500 ms RTT haben, kommt es von Anfang an zu einer Verzögerung von 1 Sekunde. Wenn die Sitzungen kurz, aber zahlreich sind, entsteht dadurch eine hohe Latenz.

Sobald die Sitzung hergestellt ist, sendet der Server Dateneinheiten, die vom Client bestätigt werden müssen. Der Server kann nur eine bestimmte Datenmenge senden, bevor er die Bestätigung der ersten Dateneinheit benötigt. Dies kann ebenfalls zu Latenz führen. Wenn eine Dateneinheit verloren geht, müssen Sie die Übertragung von dort aus fortsetzen und so zusätzliche Latenz erzeugen.

Auf IP-Ebene kommt es zu Fragmentierung (auch wenn dies heute recht selten vorkommt). Wenn Sie 1501-Byte-Frames senden und die andere Seite nur eine MTU von 1500 unterstützt, senden Sie für genau dieses letzte Datenbit ein zusätzliches IP-Paket. Dies kann durch die Verwendung von Jumbo-Frames überwunden werden.

Der beste Weg, den TCP/IP-Durchsatz zu erhöhen, besteht darin, die Latenzzeit so weit wie möglich zu reduzieren und Übertragungsfehler so weit wie möglich zu vermeiden. Ich kenne keine Kernel-Optimierungen, bin mir aber sicher, dass jemand welche findet.

Antwort4

Wahrscheinlich nicht die Antwort, nach der Sie suchen: Die Hauptursache für Latenz in einem WAN ist die Lichtgeschwindigkeit (es ist viel zu langsam!). Außerdem neigen gesättigte Verbindungen mit einem großen Puffer auf dem Weg dazu, eine beeindruckende Latenz zu erreichen.

verwandte Informationen