Ändern des TCP-RTO-Werts unter Linux

12

Ich möchte den TCP-RTO- Wert (Timeout für erneute Übertragung) für eine Verbindung ändern , und einige von mir vorgenommene Lektüren deuten darauf hin, dass ich dies tun könnte, zeigen jedoch nicht, wo und wie ich ihn ändern kann.

Ich habe mir die /proc/sys/net/ipv4Variablen angesehen, aber keine der Variablen bezieht sich auf RTO. Ich würde mich freuen, wenn mir jemand sagen kann, wie ich diesen Wert ändern kann.

obiigbe91
quelle
Das funktioniert bei mir nicht. Zumindest das Einfügen von 'ms' in die rto-Zeit gibt mir einen Fehler! Ich habe den Befehl zum Laufen gebracht, aber ss -i sagt etwas anderes. Außerdem existieren die 2 sysctl-Variablen nicht. Ich laufe auf einem 4.4 Kernel
Mark Seger
Ich habe eine neuere Distribution ausprobiert und hatte ip route replacestattdessen Erfolg - anscheinend hat sich die ip routeSyntax ein wenig geändert. Ich konnte die Änderung jedoch erfolgreich vornehmen. Nur um zu beachten, sollten Sie die Antwort kommentieren, nicht die Frage, wenn Sie mich
Adam C

Antworten:

30

Der Grund, warum Sie die RTO nicht speziell ändern können, ist, dass es sich nicht um einen statischen Wert handelt. Stattdessen (natürlich mit Ausnahme des anfänglichen SYN) basiert es auf der RTT (Round Trip Time) für jede Verbindung. Tatsächlich basiert es auf einer geglätteten Version von RTT und der RTT-Varianz, wobei einige Konstanten in die Mischung geworfen werden. Daher ist es ein dynamischer, berechneter Wert für jede TCP-Verbindung, und ich empfehle diesen Artikel , in dem die Berechnung und die RTO im Allgemeinen ausführlicher behandelt werden.

Ebenfalls relevant ist RFC 6298, in dem (unter anderem) Folgendes angegeben ist :

Wenn RTO berechnet wird und weniger als 1 Sekunde beträgt, MUSS die RTO auf 1 Sekunde aufgerundet werden.

Setzt der Kernel RTO dann immer auf 1 Sekunde? Unter Linux können Sie die aktuellen RTO-Werte für Ihre offenen Verbindungen anzeigen, indem Sie den folgenden ss -iBefehl ausführen:

State       Recv-Q Send-Q                                                  Local Address:Port     Peer Address:Port
ESTAB       0      0                                                           10.0.2.15:52861   216.58.219.46:http
     cubic rto:204 rtt:4/2 cwnd:10 send 29.2Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:ssh          10.0.2.2:52586
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:52864   216.58.219.46:http
     cubic rto:204 rtt:4.5/4.5 cwnd:10 send 26.0Mbps rcv_space:14600

Das Obige ist die Ausgabe einer VM, bei der ich mit SSH angemeldet bin und über die einige Verbindungen zu google.com geöffnet sind. Wie Sie sehen können, ist die RTO tatsächlich auf 200 ish (Millisekunden) eingestellt. Sie werden feststellen, dass dies nicht auf den 1-Sekunden-Wert des RFC gerundet ist, und Sie können auch denken, dass es ein wenig hoch ist. Das liegt daran, dass bei RTO für Linux minimale (200 Millisekunden) und maximale (120 Sekunden) Grenzen im Spiel sind (eine ausführliche Erklärung dafür finden Sie in dem Artikel, den ich oben verlinkt habe).

Sie können den RTO-Wert also nicht direkt ändern, aber für verlustbehaftete Netzwerke (wie drahtlose Netzwerke) können Sie versuchen, F-RTO zu optimieren (dies ist je nach Distribution möglicherweise bereits aktiviert). Es gibt tatsächlich zwei verwandte Optionen im Zusammenhang mit F-RTO, die Sie optimieren können (gute Zusammenfassung hier ):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

Je nachdem, wofür Sie optimieren möchten, können diese nützlich sein oder auch nicht.

BEARBEITEN: Nachverfolgung der Möglichkeit, die rto_min / max-Werte für TCP anhand der Kommentare zu optimieren.

Sie können die globale Mindest-RTO für TCP nicht ändern (abgesehen davon können Sie dies für SCTP tun - diese werden in sysctl angezeigt), aber die gute Nachricht ist, dass Sie den Mindestwert der RTO für eine Route anpassen können Basis. Hier ist meine Routing-Tabelle auf meiner CentOS-VM:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0

Ich kann den Wert für rto_min auf der Standardroute wie folgt ändern:

ip route change default via 10.0.2.2 dev eth0 rto_min 5ms

Und jetzt sieht meine Routing-Tabelle so aus:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0  rto_min lock 5ms

Lassen Sie uns abschließend eine Verbindung herstellen und prüfen, ss -iob dies eingehalten wurde:

ss -i
State       Recv-Q Send-Q                                               Local Address:Port                                                   Peer Address:Port   
ESTAB       0      0                                                        10.0.2.15:ssh                                                        10.0.2.2:50714   
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                        10.0.2.15:39042                                                 216.58.216.14:http    
     cubic rto:15 rtt:5/2.5 cwnd:10 send 23.4Mbps rcv_space:14600

Erfolg! Die RTO auf der HTTP-Verbindung (nach der Änderung) beträgt 15 ms, während die SSH-Verbindung (vor der Änderung) wie zuvor 200+ beträgt.

Ich mag diesen Ansatz tatsächlich - er ermöglicht es Ihnen, den niedrigeren Wert auf geeigneten Routen festzulegen, anstatt global, wo er anderen Verkehr beeinträchtigen könnte. In ähnlicher Weise (siehe IP-Manpage ) können Sie die anfängliche rtt-Schätzung und die anfängliche rttvar für die Route anpassen (wird bei der Berechnung der dynamischen RTO verwendet). Es ist zwar keine vollständige Lösung für Optimierungen, aber ich denke, die meisten wichtigen Teile sind vorhanden. Sie können die maximale Einstellung nicht anpassen, aber ich denke, dass dies im Allgemeinen auf keinen Fall so nützlich sein wird.

Adam C.
quelle
Vielen Dank an @Adam C für die Klarstellung, aber Sie haben die Min (200 Milli) und Max (120 Sek.) Erwähnt. Kann ich diese ändern (Min oder Max)? wenn ja, wie? ...
obiigbe91
Ich glaube, sie sind Konstanten im Code, und ich kenne keine Möglichkeit, sie dynamisch festzulegen, werde aber ein bisschen graben und sehen, da ich davon ausgehe, dass das Ändern des Codes und das Kompilieren Ihres eigenen Kernels ein bisschen viel ist :)
Adam C
Ich habe herausgefunden, wie man rto_min optimiert und es und ein paar andere verwandte Dinge in die Antwort aufgenommen :)
Adam C
Warum gibt es so etwas nicht rto_max? Wie legen wir ein globales maximales Timeout fest?
est
Wenn Sie das Minimum festlegen (oder die Standardeinstellung akzeptieren) und dann die Anzahl der zulässigen Wiederholungsversuche ( net.ipv4.tcp_retries1und eines net.ipv4.tcp_retries2ähnlichen IIRC) ändern, können Sie meines Erachtens ein RTO-Maximum erreichen.
Adam C