Latenz in TCP / IP-over-Ethernet-Netzwerken


7

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

  • Erklären Sie die Ursachen für die Latenz in TCP / IP-over-Ethernet-Netzwerken.
  • Erwähnen Sie Tools, um nach Dingen Ausschau zu halten, 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 verringern (Nagle, Socket-Puffer usw.).

Das nächste, das mir bekannt ist , ist dieses Dokument , aber es ist ziemlich kurz.

Alternativ können Sie die oben genannten Fragen auch direkt beantworten.

edit Um klar zu sein, geht es nicht nur um "abnormale" Latenz, sondern allgemein um Latenz. Darüber hinaus geht es speziell um TCP / IP-over-Ethernet und nicht um andere Protokolle (auch wenn sie bessere Latenzmerkmale aufweisen).


Natürlich werde ich Sie nicht beleidigen, indem ich Sie frage, ob Sie die Verbindung mit einer IP-Adresse und nicht mit einem Namen initiieren, der über DNS aufgelöst werden muss - und das wäre nicht auf die TCP-Latenz zurückzuführen ...
e2-e4

1
@ ring0 - Das ist sicherlich eine gute Möglichkeit, jemanden "nicht zu beleidigen".
ErnieTheGeek

Antworten:


9

In Bezug auf Kernel-Tunables für die Latenz fällt Folgendes auf:

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

Aus der Dokumentation :

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

Sie können den Nagle-Algorithmus in Ihrer Anwendung (der die TCP-Ausgabe bis zur maximalen Segmentgröße puffert) auch mit folgenden Funktionen 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, dass Pakete erneut "genagelt" werden. Beachten Sie jedoch, dass dies TCP_NODELAYmöglicherweise nicht immer das tut, was Sie erwarten, und in einigen Fällen die Leistung beeinträchtigen kann. Wenn Sie beispielsweise Massendaten senden, möchten Sie den Durchsatz pro Paket maximieren TCP_CORK. Wenn Sie eine Anwendung haben, die sofortige Interaktivität erfordert (oder bei der die Antwort viel größer als die Anforderung ist, wodurch der Overhead negiert wird), verwenden Sie TCP _NODELAY. Auf einer anderen Anmerkung, ist dieses Verhalten Linux-spezifisch und BSD ist wahrscheinlich anders, so caveat Administrator .

Stellen Sie sicher, dass Sie gründliche Tests mit Ihrer Anwendung und Infrastruktur durchführen.


(+1) Danke, genau diese Art von Informationen suche ich.
NPE

TCP_NODELAY ist ein großartiger Tipp, aber ich habe in der Praxis festgestellt, dass das Festlegen von tcp_low_latency keinen Einfluss auf die Latenz hat. Vielleicht gibt es ein esoterisches Szenario, in dem es einen Unterschied macht, aber wir haben mit verschiedenen Netzwerkkarten und einer Reihe von Kerneln versucht, eine bessere Latenz zu erreichen, und sehen bei dieser Einstellung keinen Unterschied.
Michael Greene

6

Nach meiner Erfahrung sind TCP Windowing- Fehler ( RFC1323, Abschnitt 2 ) die Hauptursache für abnormale Latenz in ansonsten fehlerfreien Hochgeschwindigkeitsnetzwerken, wobei Fehler in Bezug auf TCP Delayed Acks ( RFC1122, Abschnitt 4.2.3.2 ) eine eng verwandte Sekunde sind . Beide Methoden sind Verbesserungen von TCP für eine bessere Handhabung von Hochgeschwindigkeitsnetzwerken. Wenn sie brechen, fallen die Geschwindigkeiten auf sehr langsame Werte. Fehler in diesen Fällen wirken sich auf große Übertragungen aus (denken Sie an Backup-Streams), bei denen extrem kleiner Transaktionsverkehr (durchschnittliche Datenübertragung liegt unter der MTU-Größe und es gibt eine Menge Hin- und Herbewegungen) weniger davon betroffen ist.

Wieder habe ich die größten Probleme mit diesen beiden Problemen gesehen, wenn zwei verschiedene TCP / IP-Stapel sprechen. Wie Windows / Linux, 2.4-Linux / 2.6-Linux, Windows / NetWare, Linux / BSD. Like to like funktioniert sehr, sehr gut. Microsoft hat den Windows-TCP / IP-Stack in Server 2008 neu geschrieben, wodurch Linux-Interoperabilitätsprobleme aufgetreten sind, die mit Server 2003 nicht bestanden haben (ich glaube, diese sind behoben, aber ich bin mir nicht 100% sicher).

Meinungsverschiedenheiten über die genaue Methode der verzögerten oder selektiven Bestätigung können zu folgenden Fällen 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 vorbei]
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 vorbei]
192.168.128.20 -> 192.168.128.5: ACK 12025

Der Durchsatz geht aufgrund aller Zeitüberschreitungen von 200 ms durch den Boden (Windows verwendet standardmäßig den Timer für verzögerte Bestätigung auf 200 ms). In diesem Fall konnten beide Seiten der Konversation TCP Delayed Ack nicht verarbeiten.

TCP-Fensterfehler sind schwerer zu bemerken, da ihre Auswirkungen weniger offensichtlich sein können. In extremen Fällen schlägt das Fenster vollständig fehl und Sie erhalten Paket-> Bestätigung-> Paket-> Bestätigung-> Paket-> Bestätigung, was sehr langsam ist, wenn Sie etwas übertragen, das deutlich größer als etwa 10 KB ist, und die grundlegende Latenz auf der Verbindung vergrößert . Der schwer zu erkennende Modus ist, wenn beide Seiten ihre Fenstergröße ständig neu aushandeln und eine Seite (der Absender) die Aushandlung nicht beachtet, für deren Verarbeitung einige Pakete erforderlich sind, bevor die Daten weiter übertragen werden können. Diese Art von Fehler wird in rot blinkenden Lichtern in Wireshark-Spuren angezeigt, zeigt sich jedoch als geringerer Durchsatz als erwartet.


Wie ich bereits erwähnt habe, neigen die oben genannten dazu, große Transfers zu plagen. Verkehr wie das Streamen von Videos oder Backup-Streams kann von ihnen wirklich erfasst werden, ebenso wie das einfache Herunterladen sehr großer Dateien (wie Linux-Distribution-ISO-Dateien). TCP Windowing wurde entwickelt, um grundlegende Latenzprobleme zu umgehen, da es das Pipelining von Daten ermöglicht. Sie müssen nicht für jedes gesendete Paket auf die Umlaufzeit warten. Sie können einfach einen großen Block senden und auf eine einzelne ACK warten, bevor Sie weitere senden.

Bestimmte Netzwerkmuster profitieren jedoch nicht von diesen Problemumgehungen. Hohe Transaktionsraten und kleine Übertragungen, wie sie beispielsweise von Datenbanken generiert werden, leiden am meisten unter der normalen Latenz auf der Leitung. Wenn die RTT hoch ist, leiden diese Workloads stark, während große Streaming-Workloads viel weniger leiden.


2

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 die Bestätigung erhalten hat, kann er jetzt Daten senden. Dies bedeutet, dass Sie zweimal auf die Roundtrip-Zeit (RTT) warten müssen, um das erste Bit aussagekräftiger Daten zu senden. Wenn Sie 500 ms RTT haben, erhalten Sie von Anfang an eine Verzögerung von 1 Sekunde. Wenn die Sitzungen nur von kurzer Dauer, aber zahlreich sind, führt dies zu einer hohen Latenz.

Sobald die Sitzung eingerichtet ist, sendet der Server Dateneinheiten, die vom Client bestätigt werden müssen. Der Server kann nur so viele Daten in freier Wildbahn senden, bevor die Bestätigung der ersten Dateneinheit erforderlich ist. Dies kann ebenfalls zu Latenz führen. Wenn eine Dateneinheit fallen gelassen wird, müssen Sie die Übertragung von dort abholen und somit eine zusätzliche Latenz erzeugen.

Auf der IP-Ebene haben Sie Fragmentierung (obwohl es heute ziemlich selten ist). Wenn Sie 1501-Byte-Frames senden und die andere Seite nur eine MTU von 1500 unterstützt, senden Sie ein zusätzliches IP-Paket für nur das letzte Datenbit. Dies kann durch die Verwendung von Jumbo-Frames überwunden werden.

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


1
Und wenn Sie sich auf Jumbo-Frames verlassen, denken Sie daran, dass Jumbo-Frames von Ende zu Ende aktiviert sein müssen, um von ihnen zu profitieren ...
Vatine

Für latenzintensive Anwendungen sind Jumbo-Frames eine schlechte Idee, auch wenn sie durchgängig unterstützt werden.
Joe

2

Im Falle des WAN ist die Lichtgeschwindigkeit ein Hauptfaktor für die Einführung der Latenz. Es dauert ein theoretisches Minimum von ~ 36,2 ms, bis Daten Nordamerika durchqueren.

Einwegfahrt entlang Glasfaserkabeln in Sekunden:

  • $ _DISTANCE_IN_MILES * (Cable_Refraction / SPEED_OF_LIGHT)

Multiplizieren Sie 1000 mal, um von Sekunden in Millisekunden zu konvertieren. Verdoppeln Sie es für die Hin- und Rückfahrt:

  • $ _DISTANCE_IN_MILES * (Cable_Refraction / SPEED_OF_LIGHT) * 1000 * 2

Hier ist die Latenz von Washington, DC nach Los Angeles, CA :

  • 2308 * (1,46 / 186000) * 1000 * 2 = 36,23311 ms

  • Lichtgeschwindigkeit (in Meilen pro Sekunde) = 186000
  • Brechungsindex des Glasfaserkabels = 1,46
  • Entfernung (von DC nach LA in Meilen) = 2308

Mehr zur Formel


1
Für Kilometer sollte die SPEED_OF_LIGHT 299.792,458 sein
artifex

1

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


Ja, du hast recht. Es dauert ein theoretisches Minimum von ~ 36,3 ms, bis Daten Nordamerika durchqueren. Siehe meine Antwort für die Berechnungen.
JamesBarnett

Das Problem der "gesättigten Verbindung mit großem Puffer" ist weitaus weiter verbreitet als die meisten glauben. Weitere Informationen finden Sie unter bufferbloat.net . Eine enorme Menge an bereitgestellten Netzwerkgeräten verfügt über übergroße Puffer. Selbst in einem Rechenzentrumszenario können Sie einige Probleme mit dem Pufferbloat verursachen, indem Sie eine 100-Mbit-Ethernet-WAN-Verbindung an einen Gigabit-Layer-3-Switch der Rechenzentrumsklasse anschließen (für den normalerweise große Puffer standardmäßig vollständig aktiviert sind).
Rmalayter


0

TCP ist ein End-to-End-Protokoll (oder Client-to-Client-Protokoll), bei dem davon ausgegangen wird, dass das Netzwerk in der Mitte nur sehr geringe Verluste aufweist. Für ein robusteres Protokoll siehe X.25 . Somit haben Sie die meiste Kontrolle über die Protokollparameter nur auf den Clients (nicht im Netzwerk).

Ein Ethernet ist ein lokales Netzwerk (LAN) (obwohl diese Definition in den letzten zehn Jahren auch um Weitverkehrsnetzwerke erweitert wurde), und man würde nur einen geringen Übertragungsverlust erwarten, wenn nicht 70% oder mehr Verkehr in einem gemeinsam genutzten Segment auftreten . Neuübertragungen sind im modernen Ethernet-Netzwerk jedoch selten, da heutzutage fast alle Ethernet-Segmente geschaltet werden.

Überlastung ist also Ihr größter Feind, wenn es um Latenz im LAN geht. Aber dann haben Sie ernstere Probleme als bloße Latenz.

Wenn Sie Latenzprobleme für Ihr Kommunikationsprotokoll ernst nehmen, sollten Sie wirklich ein paketvermitteltes Protokoll in Betracht ziehen, im Gegensatz zu einem Protokoll für virtuelle Verbindungen wie UDP oder RTMP.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.