Windows TCP Window Scaling Das Plateau wurde zu früh erreicht


50

Szenario: Wir haben eine Reihe von Windows-Clients, die regelmäßig große Dateien (FTP / SVN / HTTP PUT / SCP) auf Linux-Server hochladen, die ca. 100-160 ms entfernt sind. Wir haben eine synchrone Bandbreite von 1 Gbit / s im Büro und die Server sind entweder AWS-Instanzen oder werden physisch in US-DCs gehostet.

Der erste Bericht war, dass Uploads auf eine neue Serverinstanz viel langsamer waren, als sie sein konnten. Dies hat sich in Tests und an verschiedenen Orten bestätigt. Clients sahen stabile 2-5 Mbit / s für den Host von ihren Windows-Systemen aus.

Ich bin iperf -sauf einer AWS-Instanz und dann auf einem Windows- Client im Büro ausgebrochen :

iperf -c 1.2.3.4

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55185
[  5]  0.0-10.0 sec  6.55 MBytes  5.48 Mbits/sec

iperf -w1M -c 1.2.3.4

[  4] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55239
[  4]  0.0-18.3 sec   196 MBytes  89.6 Mbits/sec

Die letztgenannte Zahl kann bei nachfolgenden Tests (Vagaries of AWS) erheblich variieren, liegt jedoch normalerweise zwischen 70 und 130 Mbit / s, was für unsere Anforderungen mehr als ausreichend ist. Während der Sitzung sehe ich:

  • iperf -c Windows SYN - Windows 64 KB, Maßstab 1 - Linux SYN, ACK: Windows 14 KB, Maßstab 9 (* 512) iperf Fensterskalierung mit 64kb Standardfenster
  • iperf -c -w1M Windows SYN - Windows 64 KB, Maßstab 1 - Linux SYN, ACK: Windows 14 KB, Maßstab 9 Iperf-Fensterskalierung mit Standard-1-MB-Fenster

Natürlich kann der Link diesen hohen Durchsatz aufrechterhalten, aber ich muss die Fenstergröße explizit festlegen, um ihn zu nutzen, was bei den meisten realen Anwendungen nicht möglich ist. Die TCP-Handshakes verwenden jeweils die gleichen Startpunkte, der erzwungene skaliert jedoch

Umgekehrt iperf -cgibt mir ein Straight von einem Linux-Client im selben Netzwerk (unter Verwendung der Systemstandardeinstellung 85 KB) Folgendes:

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 33263
[  5]  0.0-10.8 sec   142 MBytes   110 Mbits/sec

Ohne Kraftaufwand skaliert es wie erwartet. Dies kann nicht an den dazwischenliegenden Hops oder unseren lokalen Switches / Routern liegen und scheint Windows 7- und Windows 8-Clients gleichermaßen zu betreffen. Ich habe viele Anleitungen zur automatischen Optimierung gelesen, in denen es jedoch in der Regel darum geht, die Skalierung insgesamt zu deaktivieren, um schlechtes Heimnetzwerk-Kit zu umgehen.

Kann mir jemand sagen, was hier passiert und wie ich es beheben kann? (Am liebsten kann ich mich über ein Gruppenrichtlinienobjekt an die Registrierung halten.)

Anmerkungen

Auf die betreffende AWS Linux-Instanz werden die folgenden Kernel-Einstellungen angewendet sysctl.conf:

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216

Ich habe die dd if=/dev/zero | ncUmleitung /dev/nullauf das Serverende verwendet, iperfum andere mögliche Engpässe auszuschließen und zu beseitigen, aber die Ergebnisse sind ähnlich. Tests mit ncftp(Cygwin, Native Windows, Linux) lassen sich auf die gleiche Weise skalieren wie die obigen iperf-Tests auf den jeweiligen Plattformen.

Bearbeiten

Ich habe hier eine weitere konsistente Sache entdeckt, die relevant sein könnte: Bildbeschreibung hier eingeben

Dies ist die erste Sekunde der 1-MB-Aufnahme, die vergrößert wird. Sie können Slow Start in Aktion sehen, wenn das Fenster vergrößert wird und der Puffer größer wird. Es gibt dann dieses winzige Plateau von ~ 0,2 s genau an dem Punkt, an dem der Standardfenster-Iperf-Test für immer abflacht. Dieser skaliert natürlich zu viel schwindligeren Höhen, aber es ist merkwürdig, dass die Skalierung eine Pause enthält (Werte sind 1022 Byte * 512 = 523264), bevor dies geschieht.

Update - 30. Juni.

Verfolgung der verschiedenen Antworten:

  • CTCP aktivieren - Das macht keinen Unterschied. Die Fensterskalierung ist identisch. (Wenn ich das richtig verstehe, erhöht diese Einstellung die Rate, mit der das Überlastungsfenster vergrößert wird, anstatt die maximale Größe, die es erreichen kann.)
  • Aktivieren von TCP-Zeitstempeln. - Auch hier keine Änderung.
  • Nagles Algorithmus - Das macht Sinn und bedeutet zumindest, dass ich diese bestimmten Punkte in der Grafik als Hinweis auf das Problem ignorieren kann.
  • PCAP - Dateien: Zip - Datei finden Sie hier: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (Anonymisierte mit bittwiste, Extrakte auf ~ 150MB wie es eine von jedem OS-Client zum Vergleich)

Update 2 - 30. Juni

O, also, nachdem ich Kyle vorgeschlagen habe, habe ich das Abladen von Schornsteinen über das TCP-Protokoll aktiviert und deaktiviert: TCP Global Parameters

----------------------------------------------
Receive-Side Scaling State          : enabled
Chimney Offload State               : disabled
NetDMA State                        : enabled
Direct Cache Acess (DCA)            : disabled
Receive Window Auto-Tuning Level    : normal
Add-On Congestion Control Provider  : ctcp
ECN Capability                      : disabled
RFC 1323 Timestamps                 : enabled
Initial RTO                         : 3000
Non Sack Rtt Resiliency             : disabled

Aber leider keine Änderung des Durchsatzes.

Ich habe hier jedoch eine Ursache / Wirkung-Frage: Die Diagramme beziehen sich auf den RWIN-Wert, der in den ACKs des Servers für den Client festgelegt ist. Habe ich bei Windows-Clients Recht, wenn ich denke, dass Linux diesen Wert nicht über diesen Tiefpunkt hinaus skaliert, weil die begrenzte CWIN des Clients verhindert, dass selbst dieser Puffer gefüllt wird? Könnte es einen anderen Grund dafür geben, dass Linux den RWIN künstlich einschränkt?

Hinweis: Ich habe zum Teufel versucht, ECN einzuschalten. aber da ist keine Veränderung.

Update 3 - 31. Juni.

Keine Änderung nach Deaktivierung der Heuristik und des RWIN-Autotunings. Die Intel-Netzwerktreiber wurden mit einer Software auf den neuesten Stand (12.10.28.0) gebracht, mit der die Funktionen der Viadevice-Manager-Registerkarten optimiert werden. Bei der Karte handelt es sich um eine integrierte Netzwerkkarte mit 82579V-Chipsatz. (Ich werde weitere Tests von Kunden mit Realtek oder anderen Anbietern durchführen.)

Ich habe mich für einen Moment auf die Netzwerkkarte konzentriert und Folgendes versucht (meistens nur, um unwahrscheinliche Schuldige auszuschließen):

  • Erhöhen Sie die Empfangspuffer von 256 auf 2 KB und die Sendepuffer von 512 auf 2 KB (beide jetzt maximal) - Keine Änderung
  • Alle IP / TCP / UDP-Prüfsummenverschiebungen wurden deaktiviert. - Keine Änderung.
  • Deaktivierte Large Send Offload - Nada.
  • IPv6, QoS-Planung deaktiviert - Nowt.

Update 3 - 3. Juli

Um die Linux-Serverseite zu beseitigen, habe ich eine Server 2012R2-Instanz gestartet und die Tests mit iperf(cygwin binary) und NTttcp wiederholt .

Bei iperfmusste ich -w1mauf beiden Seiten explizit angeben, bevor die Verbindung über ~ 5Mbit / s skalieren würde. (Ich könnte übrigens überprüft werden und die BDP von ~ 5Mbit bei 91ms Latenz beträgt fast genau 64kb. Finde das Limit ...)

Die ntttcp-Binärdateien zeigten nun eine solche Einschränkung. Wenn ich ntttcpr -m 1,0,1.2.3.5auf dem Server und ntttcp -s -m 1,0,1.2.3.5 -t 10auf dem Client arbeite, sehe ich einen viel besseren Durchsatz:

Copyright Version 5.28
Network activity progressing...


Thread  Time(s) Throughput(KB/s) Avg B / Compl
======  ======= ================ =============
     0    9.990         8155.355     65536.000

#####  Totals:  #####

   Bytes(MEG)    realtime(s) Avg Frame Size Throughput(MB/s)
================ =========== ============== ================
       79.562500      10.001       1442.556            7.955

Throughput(Buffers/s) Cycles/Byte       Buffers
===================== =========== =============
              127.287     308.256      1273.000

DPCs(count/s) Pkts(num/DPC)   Intr(count/s) Pkts(num/intr)
============= ============= =============== ==============
     1868.713         0.785        9336.366          0.157

Packets Sent Packets Received Retransmits Errors Avg. CPU %
============ ================ =========== ====== ==========
       57833            14664           0      0      9.476

8MB / s bringt es auf die Level, die ich mit explizit großen Fenstern in bekommen habe iperf. Seltsamerweise sind 80 MB in 1273 Puffern wieder ein 64-kB-Puffer. Ein weiterer Wireshark zeigt eine gute, variable RWIN, die vom Server zurückkommt (Skalierungsfaktor 256) und die der Client zu erfüllen scheint. Vielleicht meldet ntttcp das Sendefenster falsch.

Update 4 - 3. Juli

Auf Anfrage von @ karyhead habe ich weitere Tests durchgeführt und ein paar weitere Captures generiert, hier: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Zwei weitere iperfs, beide von Windows zu demselben Linux-Server wie zuvor (1.2.3.4): Einer mit einer Socket-Größe von 128 KB und einem Standardfenster von 64 KB (wieder auf ~ 5 MBit / s beschränkt) und einer mit einem Sendefenster von 1 MB und einem Standard-Socket von 8 KBit / s Größe. (skaliert höher)
  • Eine ntttcpAblaufverfolgung von demselben Windows-Client zu einer Server 2012R2 EC2-Instanz (1.2.3.5). hier lässt sich der durchsatz gut skalieren. Hinweis: NTttcp führt an Port 6001 etwas Ungewöhnliches aus, bevor die Testverbindung geöffnet wird. Ich bin nicht sicher, was dort passiert.
  • Ein FTP-Datentrace, /dev/urandombei dem mit Cygwin 20 MB auf einen nahezu identischen Linux-Host (1.2.3.6) hochgeladen werden ncftp. Wieder ist die Grenze da. Das Muster ist mit Windows Filezilla ähnlich.

Durch Ändern der iperfPufferlänge wird zwar der erwartete Unterschied zum Zeitablaufdiagramm (viel mehr vertikale Abschnitte) erzielt, der tatsächliche Durchsatz bleibt jedoch unverändert.


11
Ein seltener Fall eines gut recherchierten Problems, der nicht offensichtlich in der Dokumentation enthalten ist. Nett - hoffen wir, dass jemand eine Lösung findet (weil ich irgendwie denke, dass ich das auch nutzen kann).
TomTom

2
Versuchen Sie, RFC 1323-Zeitstempel zu aktivieren, da diese in Windows standardmäßig deaktiviert sind, während sie in Linux standardmäßig aktiviert sind. netsh int tcp set global timestamps=enabled
Brian,

3
Die Verzögerung von 200 ms ist wahrscheinlich der aktive Nagle-Algorithmus. Da Daten über eine bestimmte Verbindung von TCP empfangen werden, wird nur dann eine Bestätigung zurückgesendet, wenn eine der folgenden Bedingungen erfüllt ist: Für das zuvor empfangene Segment wurde keine Bestätigung gesendet. Ein Segment wird empfangen, aber innerhalb von 200 Millisekunden kommt kein anderes Segment für diese Verbindung an.
Greg Askew

2
Gibt es eine Chance, ein paar Paketerfassungen von einem der langsameren Absender irgendwo abzulegen?
Kyle Brandt

Ich habe mein OP mit den Ergebnissen dieser Tests und Links zu repräsentativen Erfassungsdateien aktualisiert.
SmallClanger

Antworten:


15

Haben Sie versucht, Compound TCP (CTCP) in Ihren Windows 7/8-Clients zu aktivieren ?

Bitte lesen Sie:

Steigerung der senderseitigen Leistung für Übertragungen mit hoher BDP

http://technet.microsoft.com/en-us/magazine/2007.01.cableguy.aspx

...

Diese Algorithmen eignen sich gut für kleine BDPs und kleinere Empfangsfenstergrößen. Wenn Sie jedoch über eine TCP-Verbindung mit einem großen Empfangsfenster und einem großen BDP verfügen , z. B. um Daten zwischen zwei Servern zu replizieren, die sich über eine Hochgeschwindigkeits- WAN-Verbindung mit einer Umlaufzeit von 100 ms befinden , vergrößern diese Algorithmen das Sendefenster nicht schnell genug, um die Bandbreite der Verbindung voll auszunutzen .

Um die Bandbreite von TCP-Verbindungen in diesen Situationen besser nutzen zu können, enthält der TCP / IP-Stapel der nächsten Generation Compound TCP (CTCP). CTCP erhöht das Sendefenster aggressiver für Verbindungen mit großen Empfangsfenstern und BDPs . CTCP versucht, den Durchsatz dieser Verbindungstypen zu maximieren, indem Verzögerungsschwankungen und -verluste überwacht werden. Darüber hinaus stellt CTCP sicher, dass sich sein Verhalten nicht negativ auf andere TCP-Verbindungen auswirkt.

...

CTCP ist auf Computern unter Windows Server 2008 standardmäßig aktiviert und auf Computern unter Windows Vista standardmäßig deaktiviert. Sie können CTCP mit dem netsh interface tcp set global congestionprovider=ctcpBefehl aktivieren . Sie können CTCP mit dem netsh interface tcp set global congestionprovider=noneBefehl deaktivieren .

Bearbeiten 30.06.2014

um zu sehen, ob CTCP wirklich "an" ist

> netsh int tcp show global

dh

Bildbeschreibung hier eingeben

PO sagte:

Wenn ich das richtig verstehe, erhöht diese Einstellung die Rate, mit der das Überlastungsfenster vergrößert wird, anstatt die maximale Größe, die es erreichen kann

CTCP vergrößert das Sendefenster aggressiv

http://technet.microsoft.com/en-us/library/bb878127.aspx

Zusammengesetztes TCP

Die vorhandenen Algorithmen, die verhindern, dass ein sendender TCP-Peer das Netzwerk überlastet, werden als Vermeidung von langsamen Starts und Überlastungen bezeichnet. Diese Algorithmen erhöhen die Anzahl der Segmente, die der Absender senden kann. Dies wird als Sendefenster bezeichnet, wenn er anfänglich Daten über die Verbindung sendet und wenn ein verlorenes Segment wiederhergestellt wird. Langsamer Start erhöht das Sendefenster um ein vollständiges TCP-Segment für jedes empfangene Bestätigungssegment (für TCP in Windows XP und Windows Server 2003) oder für jedes bestätigte Segment (für TCP in Windows Vista und Windows Server 2008). Durch die Vermeidung von Überlastungen wird das Sendefenster für jedes bestätigte Datenfenster um ein volles TCP-Segment erhöht.

Diese Algorithmen eignen sich gut für LAN-Mediengeschwindigkeiten und kleinere TCP-Fenstergrößen. Wenn Sie jedoch eine TCP-Verbindung mit einem großen Empfangsfenster und einem Produkt mit großer Bandbreitenverzögerung (hohe Bandbreite und hohe Verzögerung) haben, z. B. das Replizieren von Daten zwischen zwei Servern, die sich über eine Hochgeschwindigkeits-WAN-Verbindung mit einer 100-ms-Umlaufzeit befinden In diesem Fall vergrößern diese Algorithmen das Sendefenster nicht schnell genug, um die Bandbreite der Verbindung voll auszunutzen. Zum Beispiel auf einen 1 Gigabit pro Sekunde (Gbps) WAN - Verbindung mit 100 ms Umlaufzeit (RTT), kann es bis zu einer Stunde für das Sendefenster zunächst zu erhöhen , um die Aufnahme großen Fenstergröße durch den Empfänger der beworbenen und sich zu erholen, wenn Segmente verloren gehen.

Um die Bandbreite von TCP-Verbindungen in diesen Situationen besser nutzen zu können, enthält der TCP / IP-Stapel der nächsten Generation Compound TCP (CTCP). CTCP erhöht das Sendefenster aggressiver für Verbindungen mit großen Empfangsfenstern und Produkten mit großer Bandbreitenverzögerung. CTCP versucht, den Durchsatz dieser Verbindungstypen zu maximieren, indem Verzögerungsschwankungen und -verluste überwacht werden . CTCP stellt außerdem sicher, dass sein Verhalten keine negativen Auswirkungen auf andere TCP-Verbindungen hat.

Bei Tests, die intern bei Microsoft durchgeführt wurden, wurden die Sicherungszeiten für große Dateien bei einer 1-Gbit / s-Verbindung mit einer 50-ms-RTT um fast die Hälfte reduziert. Verbindungen mit einem Verzögerungsprodukt mit größerer Bandbreite können eine noch bessere Leistung erzielen. CTCP und Receive Window Auto-Tuning arbeiten zusammen, um die Verbindungsauslastung zu erhöhen, und können zu erheblichen Leistungssteigerungen bei Produktverbindungen mit großer Bandbreite und Verzögerung führen.


3
Als Ergänzung zu dieser Antwort enthält das Powershell-Äquivalent in Server 2012 / Win8.1 Set-NetTCPSettingden -CongestionProviderParameter ..., der CCTP, DCTCP und Default akzeptiert. Windows-Client und -Server verwenden unterschiedliche Standard-Überlastungsanbieter. technet.microsoft.com/en-us/library/hh826132.aspx
Ryan Ries

Ich verstehe, worauf du hinaus willst, aber es scheint nicht zuzutreffen. Aus diesem iperfGrund lief ich 30 Minuten und das Fenster skalierte immer noch nie über ~ 520 KB. Etwas anderes schränkt den CWND ein, bevor dieser aggressive Algorithmus irgendwelche Vorteile zeigen kann.
SmallClanger

Es gibt einen alten (bereits behobenen) Vista-Fehler, der diese Art von Problemen bei der Übertragung von Nicht-HTML-Protokollen verursachte. Sieht Ihr Problem genauso aus, wenn Sie dieselbe Datei per HTML oder beispielsweise per FTP übertragen?
Pat

@ Pat - Das tut es. SVN-Commits (über HTTP und HTTPS) und FTP-Übertragungen auf ein anderes System unter AWS weisen ebenfalls dieselben Grenzwerte auf.
SmallClanger

Wie wäre es mit der Firewall von Win Client? kannst du mit komplett abgeschalteter firewall testen? siehe hier: ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Pat

12

Klärung des Problems:

TCP hat zwei Fenster:

  • Das Empfangsfenster: Wie viele Bytes noch im Puffer sind. Dies ist eine Flusskontrolle, die vom Empfänger vorgegeben wird. Sie können die Größe des Empfangsfensters im Wireshark sehen, da es sich aus der Fenstergröße und dem Fensterskalierungsfaktor im TCP-Header zusammensetzt. Beide Seiten der TCP-Verbindung kündigen ihr Empfangsfenster an. Im Allgemeinen ist es jedoch diejenige, die Sie interessiert, die den Großteil der Daten empfängt. In Ihrem Fall ist es der "Server", da der Client auf den Server hochlädt
  • Das Überlastungsfenster. Dies ist eine Flusskontrolle, die vom Absender vorgegeben wird. Dies wird vom Betriebssystem verwaltet und nicht im TCP-Header angezeigt. Es steuert die Geschwindigkeit, mit der Daten gesendet werden.

In der von Ihnen angegebenen Erfassungsdatei. Wir können sehen, dass der Empfangspuffer niemals überläuft:

Bildbeschreibung hier eingeben

Meine Analyse ist, dass der Absender nicht schnell genug sendet, weil das Sendefenster (auch als Engpass-Kontrollfenster bezeichnet) nicht genug geöffnet ist, um die RWIN des Empfängers zu befriedigen. Kurz gesagt, der Empfänger sagt "Give me More" und wenn Windows der Absender ist, sendet er nicht schnell genug.

Dies wird durch die Tatsache belegt, dass in der obigen Grafik die RWIN offen bleibt und bei einer Umlaufzeit von 0,09 Sekunden und einer RWIN von ~ 500.000 Byte ein maximaler Durchsatz gemäß dem Bandbreitenverzögerungsprodukt von (500000) erwartet werden kann /0.09) * 8 = ~ 42 Mbit / s (und Sie erhalten nur ungefähr ~ 5 in Ihrem Gewinn zu Linux-Gefangennahme).

Wie man es repariert?

Ich weiß es nicht. interface tcp set global congestionprovider=ctcpKlingt nach einer richtigen Vorgehensweise, da dadurch das Sendefenster vergrößert wird (ein anderer Begriff für das Überlastungsfenster). Sie sagten, das funktioniert nicht. Also nur um sicherzugehen:

  1. Haben Sie nach der Aktivierung einen Neustart durchgeführt?
  2. Ist der Schornstein eingeschaltet? Wenn dies der Fall ist, schalten Sie es als Experiment aus. Ich weiß nicht, was genau ausgelagert wird, wenn dies aktiviert ist, aber wenn die Steuerung des Sendefensters eine davon ist, hat der Überlastungsprovider möglicherweise keine Auswirkung, wenn dies aktiviert ist ... Ich vermute nur ...
  3. Ich denke auch, dass dies vor Windows 7 sein könnte, aber Sie könnten versuchen, die beiden Registrierungsschlüssel DefaultSendWindow und DefaultReceiveWindow in HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameters hinzuzufügen und damit zu spielen. Wenn diese sogar funktionieren, haben Sie wahrscheinlich ctcp off.
  4. Noch eine Vermutung, probieren Sie es aus netsh interface tcp show heuristics. Ich denke, das könnte RWIN sein, aber es sagt nicht, also spielen Sie vielleicht mit dem Deaktivieren / Aktivieren, falls es das Sendefenster beeinflusst.
  5. Stellen Sie außerdem sicher, dass Ihre Treiber auf Ihrem Testclient auf dem neuesten Stand sind. Vielleicht ist etwas kaputt.

Ich würde all diese Experimente mit all Ihren Offloading-Funktionen versuchen, um die Möglichkeit auszuschließen, dass die Netzwerktreiber einige Dinge umschreiben / modifizieren (behalten Sie die CPU im Auge, während das Offloading deaktiviert ist). Die TCP_OFFLOAD_STATE_DELEGATED-Struktur scheint zumindest zu implizieren, dass ein CWnd-Offloading zumindest möglich ist.


2
Ich habe deine "Antwort" gemeldet, weil deine keine Antwort ist. Ich wurde sofort abgewählt; Jetzt sehe ich, wie "Leute" Ihre "Nein-Antwort"
Pat

1
@Pat: Sie können auch auf die Abstimmungsnummer klicken, um die Aufschlüsselung der Upvotes / Downvotes anzuzeigen. Derzeit haben Sie keine Bewertungen für Ihre Antwort. Meine Antwort löst sein Problem nicht (aber noch keine Antwort), sondern erklärt und lokalisiert das Problem (hoffentlich richtig!), Was ein wichtiger Schritt bei der Fehlerbehebung ist.
Kyle Brandt

@ Kyle Brandt wenn du deine akzeptierst ist das keine antwort ich frage mich warum es nicht "automatisch" ohne weitere überlegung entfernt wird ??? und du liegst falsch; Ich habe eine Gegenstimme (Ablehnung) "sobald" ich Ihre "Antwort" gemeldet habe; der wurde noch nicht entfernt. Anscheinend spielst du hier nach "speziellen" Regeln.
Pat

1
@Pat Wenn es hilft, war Kyles Nichtbeantwortung unglaublich hilfreich. Ich habe jetzt eine klarere Vorstellung davon, welche Puffer begrenzt sind, und bin daher meiner Meinung nach einer richtigen Lösung ein wenig näher gekommen. Manchmal können Fragen wie diese eine gemeinschaftliche Anstrengung sein, die mit ein wenig umsichtiger Bearbeitung zu einem richtigen Q und einem richtigen A werden kann .
SmallClanger

@SmallClanger mit allem Respekt, SF hat eine Reihe von Regeln, die von allen Benutzern befolgt werden sollten, einschließlich Kyle Brandt; Wenn es sich nicht um eine Antwort handelt, muss diese gelöscht oder als Kommentar verschoben werden, unabhängig davon, wie viele Freunde er im Club der "Moderatoren" hat.
Pat

5

Hier gibt es einige großartige Informationen von @Pat und @Kyle. Achten Sie auf jeden Fall auf @ Kyles Erklärung der TCP-Empfangs- und -Sendefenster. Ich glaube, das hat Verwirrung gestiftet. Um die Sache noch weiter zu verwirren, verwendet iperf den Begriff "TCP-Fenster" mit einer -wEinstellung, die in Bezug auf das Empfangs-, Sende- oder Gesamtgleitfenster mehrdeutig ist. Tatsächlich wird der Socket-Sendepuffer für die -c(Client-) Instanz und der Socket-Empfangspuffer für die -s(Server-) Instanz festgelegt. In src/tcp_window_size.c:

if ( !inSend ) {
    /* receive buffer -- set
     * note: results are verified after connect() or listen(),
     * since some OS's don't show the corrected value until then. */
    newTCPWin = inTCPWin;
    rc = setsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
                     (char*) &newTCPWin, sizeof( newTCPWin ));
} else {
    /* send buffer -- set
     * note: results are verified after connect() or listen(),
     * since some OS's don't show the corrected value until then. */
    newTCPWin = inTCPWin;
    rc = setsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
                     (char*) &newTCPWin, sizeof( newTCPWin ));
}

Wie Kyle erwähnt, liegt das Problem nicht am Empfangsfenster auf der Linux-Box, aber der Absender öffnet das Sendefenster nicht genug. Es ist nicht so, dass es sich nicht schnell genug öffnet, es begrenzt nur auf 64k.

Die Standardgröße des Socket-Puffers unter Windows 7 beträgt 64 KB. In der Dokumentation wird die Größe des Socket-Puffers im Verhältnis zum Durchsatz bei MSDN beschrieben

Wenn Sie Daten über eine TCP-Verbindung mit Windows-Sockets senden, ist es wichtig, dass eine ausreichende Menge an Daten in TCP aussteht (gesendet, aber noch nicht bestätigt), um den höchsten Durchsatz zu erzielen. Der ideale Wert für die ausstehende Datenmenge, um den besten Durchsatz für die TCP-Verbindung zu erzielen, wird als ideale ISB-Größe (Send Backlog) bezeichnet. Der ISB-Wert ist eine Funktion des Bandbreitenverzögerungsprodukts der TCP-Verbindung und des angekündigten Empfangsfensters des Empfängers (und teilweise des Ausmaßes der Überlastung im Netzwerk).

Ok, bla bla, jetzt geht's los:

Anwendungen, die jeweils eine blockierende oder nicht blockierende Sendeanforderung ausführen, verlassen sich normalerweise auf die interne Sendepufferung von Winsock, um einen angemessenen Durchsatz zu erzielen. Das Sendepufferlimit für eine bestimmte Verbindung wird durch die Socket-Option SO_SNDBUF gesteuert. Für die blockierende und die nicht blockierende Sendemethode bestimmt das Sendepufferlimit, wie viele Daten in TCP ausstehen . Wenn der ISB-Wert für die Verbindung größer als das Sendepufferlimit ist, ist der auf der Verbindung erzielte Durchsatz nicht optimal.

Der durchschnittliche Durchsatz Ihres letzten Iperf-Tests unter Verwendung des 64k-Fensters beträgt 5,8 Mbit / s. Das ist aus Statistik> Zusammenfassung in Wireshark, die alle Bits zählt. Wahrscheinlich zählt iperf den TCP-Datendurchsatz, der 5,7 Mbit / s beträgt. Die gleiche Leistung sehen wir auch beim FTP-Test mit ~ 5,6 Mbit / s.

Der theoretische Durchsatz mit einem 64k Sendepuffer und 91ms RTT beträgt .... 5.5Mbps. Nah genug für mich.

Wenn wir uns Ihren 1-MB-Fenster-Iperf-Test ansehen, beträgt der Tput 88,2 Mbit / s (86,2 Mbit / s nur für TCP-Daten). Der theoretische Durchsatz bei einem 1-MB-Fenster beträgt 87,9 MBit / s. Wieder nah genug für die Regierungsarbeit.

Dies zeigt, dass der Sende-Socket-Puffer das Sendefenster direkt steuert und zusammen mit dem Empfangsfenster von der anderen Seite den Durchsatz steuert. Das angegebene Empfangsfenster bietet Platz, sodass wir nicht auf den Empfänger beschränkt sind.

Was ist mit diesem Autotuning-Geschäft? Verarbeitet Windows 7 das nicht automatisch? Wie bereits erwähnt, verwaltet Windows die automatische Skalierung des Empfangsfensters, kann aber auch den Sendepuffer dynamisch verwalten. Kehren wir zur MSDN-Seite zurück:

Unter Windows 7 und Windows Server 2008 R2 wurde die dynamische Sendepufferung für TCP hinzugefügt. Standardmäßig ist die dynamische Sendepufferung für TCP aktiviert, es sei denn, eine Anwendung setzt die Socket-Option SO_SNDBUF für den Stream-Socket.

iperf verwendet , SO_SNDBUFwenn die Verwendung von -wOption, so dynamische Sende Pufferung deaktiviert sein würde. Wenn Sie es jedoch nicht verwenden, -wwird es nicht verwendet SO_SNDBUF. Die dynamische Sendepufferung sollte standardmäßig aktiviert sein. Sie können jedoch Folgendes überprüfen:

netsh winsock show autotuning

Die Dokumentation besagt, dass Sie es deaktivieren können mit:

netsh winsock set autotuning off

Aber das hat bei mir nicht funktioniert. Ich musste eine Registrierungsänderung vornehmen und dies auf 0 setzen:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DynamicSendBufferDisable

Ich denke nicht, dass es helfen wird, dies zu deaktivieren. Es ist nur eine FYI.

Warum überschreitet Ihr Sendepuffer beim Senden von Daten an eine Linux-Box mit viel Platz im Empfangsfenster nicht die Standardgröße von 64 KB? Gute Frage. Linux-Kernel haben auch einen Autotuning-TCP-Stack. So wie T-Pain und Kanye zusammen ein Autotune-Duett machen, hört es sich vielleicht nicht gut an. Vielleicht liegt ein Problem damit vor, dass diese beiden Autotuning-TCP-Stacks miteinander kommunizieren.

Eine andere Person hatte genau wie Sie ein Problem und konnte es mit einer Registrierungsänderung beheben, um die Standardgröße des Sendepuffers zu erhöhen. Leider scheint das nicht mehr zu funktionieren, zumindest nicht für mich, als ich es ausprobiert habe.

An diesem Punkt denke ich, dass es klar ist, dass der begrenzende Faktor die Sendepuffergröße auf dem Windows-Host ist. Was kann ein Mädchen tun, wenn es nicht dynamisch wächst?

Du kannst:

  • Verwenden Sie Anwendungen, mit denen Sie den Sendepuffer festlegen können, z. B. Fensteroption
  • Verwenden Sie einen lokalen Linux-Proxy
  • Verwenden Sie einen Remote-Windows-Proxy?
  • Öffnen Sie einen Fall mit Microsofhahahahahahaha
  • Bier

Haftungsausschluss: Ich habe viele, viele Stunden damit verbracht, dies zu recherchieren, und es ist nach bestem Wissen und Gewissen von Google-Fu korrekt. Aber ich würde nicht auf das Grab meiner Mutter schwören (sie lebt noch).


Fantastischer Eingang; Dankeschön. Ich verwende iperf 2.0.4, experimentiere mit den Einstellungen und aktualisiere mein OP auch mit neuen Kappen.
SmallClanger

Ok, ich habe meine "Antwort" basierend auf mehr Forschung und Ihren letzten Tests
aktualisiert

Vielen Dank. Zumindest teilweise ist es schön zu wissen, dass ich nicht nur verrückt werde. Ich habe ein paar Blogs / Threads aus den XP / 2003-Tagen gelesen, die diese Registrierungseinstellungen empfehlen, aber sie wurden vor Vista / 2008 geschrieben und ich bin mir ziemlich sicher, dass sie ab Vista ignoriert werden. Ich denke, ich werde tatsächlich ein Ticket mit MS darüber erheben (wünsche mir Glück)
SmallClanger

1
Ein nützliches Tool, auf das ich bei meinen Recherchen gestoßen bin, war tcpanalyzer.exe im SDK ( microsoft.com/en-us/download/details.aspx?id=8279 ). Es ist ein grafischer Netstat, mit dem Sie eine einzelne Verbindung auswählen und die TCP-Statistiken wie RTT, CWND, Neuübertragungen usw. abrufen können. Ich konnte den CWND weit über die Größe des Sendepuffers hinaus öffnen lassen, aber der Tput wurde nicht erhöht und wireshark verifiziert dass der Sendepuffer noch begrenzt ist.
Karyhead

1
Ich habe in mehreren Foren Kommentare zu "netsh" -Befehlen gefunden, die nicht wie in 7/8 angekündigt funktionieren, und Menschen, die gezwungen sind, die entsprechenden Registrierungseinträge manuell einzugeben. Ich frage mich, ob mit der CTCP-Option so etwas passieren könnte.
Pat

4

Sobald Sie den TCP-Stack optimiert haben, besteht möglicherweise weiterhin ein Engpass in der Winsock-Ebene. Ich habe festgestellt, dass die Konfiguration von Winsock (Treiber für Zusatzfunktionen in der Registrierung) einen großen Unterschied für die Upload-Geschwindigkeit (das Übertragen von Daten auf den Server) in Windows 7 darstellt. Microsoft hat einen Fehler im TCP-Autotuning für nicht blockierende Sockets festgestellt - nur das Art Socket, den Browser benutzen ;-)

Fügen Sie den DWORD-Schlüssel für DefaultSendWindow hinzu und setzen Sie ihn auf BDP oder höher. Ich benutze 256000.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\AFD\Parameters\DefaultSendWindow

Das Ändern der Winsock-Einstellung für Downloads kann hilfreich sein - fügen Sie einen Schlüssel für DefaultReceiveWindow hinzu.

Sie können mit verschiedenen Einstellungen der Socket-Ebene experimentieren, indem Sie den Fiddler- Proxy und die Befehle verwenden, um die Größe des Client- und Server-Socket-Puffers anzupassen:

prefs set fiddler.network.sockets.Server_SO_SNDBUF 65536 

fiddler.network.sockets.Client_SO_SNDBUF
fiddler.network.sockets.Client_SO_RCVBUF
fiddler.network.sockets.Server_SO_SNDBUF
fiddler.network.sockets.Server_SO_RCVBUF

Tolle zusätzliche Informationen. Haben Sie zufällig einen Referenzlink für den MS-Fehler?
SmallClanger

3

Nachdem Sie alle Analysen in den Antworten gelesen haben, hört sich dieses Problem so an, als würden Sie Windows7 / 2008R2 aka Windows 6.1 ausführen

Der Netzwerkstapel (TCP / IP & Winsock) in Windows 6.1 war schrecklich fehlerhaft und wies eine Reihe von Fehlern und Leistungsproblemen auf, die Microsoft schließlich über viele Jahre des Hotfixing seit der ersten Veröffentlichung von 6.1 behoben hat.

Die beste Möglichkeit, diese Hotfixes anzuwenden, besteht darin, alle relevanten Seiten auf support.microsoft.com manuell zu durchsuchen und die LDR-Versionen der Hotfixes für den Netzwerkstapel manuell anzufordern und herunterzuladen (davon gibt es Dutzende).

Um die relevanten Hotfixes zu finden, müssen Sie www.bing.com mit der folgenden Suchabfrage verwenden site:support.microsoft.com 6.1.7601 tcpip.sys

Sie müssen auch wissen, wie LDR / GDR-Hotfix-Züge in Windows 6.1 funktionieren

Normalerweise habe ich meine eigene Liste von LDR-Fixes (nicht nur Netzwerkstapel-Fixes) für Windows 6.1 geführt und diese Fixes dann proaktiv auf alle Windows 6.1-Server / -Clients angewendet, auf die ich gestoßen bin. Es war eine sehr zeitaufwändige Aufgabe, regelmäßig nach neuen LDR-Hotfixes zu suchen.

Glücklicherweise hat Microsoft die Verwendung von LDR-Hotfixes mit neueren Betriebssystemversionen eingestellt und Bugfixes sind jetzt über automatische Update-Dienste von Microsoft verfügbar.

UPDATE : Nur ein Beispiel für viele Netzwerkfehler in Windows7SP1 - https://support.microsoft.com/en-us/kb/2675785

UPDATE 2 : Hier ist ein weiterer Hotfix, der einen Netsh-Schalter hinzufügt, um die Fensterskalierung nach der zweiten Neuübertragung eines SYN-Pakets zu erzwingen (standardmäßig ist die Fensterskalierung deaktiviert, nachdem 2 SYN-Pakete erneut übertragen wurden). Https://support.microsoft.com/en- us / kb / 2780879


Danke Christoph; einige sehr interessante neue Eingaben zu diesem und jenem 'Merkmal' der SYN-Neuübertragung sind sehr merkwürdig; Das gestalterische Ziel dahinter sehe ich überhaupt nicht. (Vielleicht eine Art grobe Stauerkennung?) Alle ursprünglichen Tests wurden unter Win7SP1 durchgeführt. Wir werden Win10 bald testen und es liegt an mir, einen Großteil davon erneut auszuführen, um zu sehen, wie es abschneidet.
SmallClanger

Mit welchem ​​Windows 10-Zweig werden Sie testen? Ich habe noch keine Erfahrung mit dem Netzwerk-Stack in Windows 10.
Christoph Wegener

Enterprise 1511 ist das, worauf wir abzielen.
SmallClanger

Aha. Es ist ziemlich schwierig, sich für einen Zweig mit Windows 10 zu entscheiden, da es so viele gibt. Ich bin bereits auf ein Problem mit Windows 10 gestoßen, bei dem ich eine bestimmte Funktion nicht verwenden konnte, weil ich mich in einem LTSB-Zweig befand. Ich wünschte, Microsoft hätte die Anzahl der verfügbaren Zweige insgesamt reduziert und stattdessen die Dokumentation darüber verbessert, welche Fixes und Features in jedem Build enthalten sind.
Christoph Wegener

1

Ich sehe, dass dies ein bisschen älter ist, aber es könnte anderen helfen.

Kurz gesagt, Sie müssen "Receive Window Auto-Tuning" aktivieren:

netsh int tcp set global autotuninglevel=normal

CTCP bedeutet nichts ohne oben aktiviert.

Wenn Sie "Receive Window Auto-Tuning" deaktivieren, bleiben Sie bei einer Paketgröße von 64 KB hängen, was sich negativ auf lange RTTs bei Breitbandverbindungen auswirkt. Sie können auch mit den Optionen "eingeschränkt" und "stark eingeschränkt" experimentieren.

Sehr gute Referenz: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html


1

Bei Windows-Clients (Windows 7) trat ein ähnliches Problem auf. Ich habe das meiste Debugging durchlaufen und den Nagle-Algorithmus, das TCP-Chimney-Offloading und jede Menge andere TCP-bezogene Einstellungsänderungen deaktiviert. Keiner von ihnen hatte irgendeine Wirkung.

Was es schließlich für mich reparierte, war das Ändern des Standard-Sendefensters in der Registrierung des AFD-Dienstes. Das Problem hängt anscheinend mit der Datei afd.sys zusammen. Ich habe mehrere Clients getestet, einige zeigten den langsamen Upload und andere nicht, aber alle waren Windows 7-Computer. Computer, die das langsame Verhalten aufwiesen, hatten dieselbe Version AFD.sys. Die Problemumgehung für die Registrierung ist für Computer mit bestimmten Versionen von AFD.sys erforderlich.

HKLM \ CurrentControlSet \ Services \ AFD \ Parameters

Add - DWORD - DefaultSendWindow

Wert - Dezimal - 1640960

Diesen Wert habe ich hier gefunden: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Ich denke, um den richtigen Wert zu verwenden, sollten Sie ihn selbst berechnen mit:

z.B. Mitgeteilter Upload: 15 Mbit / s = 15.000 Kbit / s

(15000/8) * 1024 = 1920000

Soweit ich weiß, sollte Client-Software diese Einstellung in der Registrierung im Allgemeinen außer Kraft setzen. Wenn dies jedoch nicht der Fall ist, wird der Standardwert verwendet, und anscheinend ist der Standardwert in einigen Versionen der Datei AFD.sys sehr niedrig.

Ich habe festgestellt, dass bei den meisten MS-Produkten das Problem des langsamen Uploads (IE, Mini-Redirector (WebDAV), FTP über Windows Explorer usw.) auftrat .

Die Datei AFD.sys wirkt sich auf alle Winsock-Verbindungen aus. Daher sollte dieses Update für FTP, HTTP, HTTPS usw. gelten.

Außerdem wurde dieses Update oben auch irgendwo aufgelistet, sodass ich es nicht gutheißen möchte, wenn es für irgendjemanden funktioniert. Allerdings waren in diesem Thread so viele Informationen enthalten, dass ich befürchtete, es könnte beschönigt worden sein.


0

Nun, ich bin selbst in eine ähnliche Situation geraten (meine Frage hier ) und musste am Ende die TCP-Skalierungsheuristik deaktivieren, das Autotuning-Profil manuell einstellen und CTCP aktivieren:

# disable heuristics
C:\Windows\system32>netsh interface tcp set heuristics wsh=disabled
Ok.

# enable receive-side scaling
C:\Windows\system32>netsh int tcp set global rss=enabled
Ok.

# manually set autotuning profile
C:\Windows\system32>netsh interface tcp set global autotuning=experimental
Ok. 

# set congestion provider
C:\Windows\system32>netsh interface tcp set global congestionprovider=ctcp
Ok. 

0

Ich habe nicht genug Punkte, um zu kommentieren, daher werde ich stattdessen eine "Antwort" posten. Ich habe ein anscheinend ähnliches / identisches Problem (siehe Serverfehlerfrage hier ). Mein (und wahrscheinlich auch Ihr) Problem ist der Sendepuffer des iperf-Clients unter Windows. Es wächst nicht über 64 KB hinaus. Windows soll den Puffer dynamisch vergrößern, wenn er vom Prozess nicht explizit dimensioniert wird. Aber dieses dynamische Wachstum findet nicht statt.

Ich bin mir nicht sicher, ob Ihr Diagramm zur Fensterskalierung die Fensteröffnung von bis zu 500.000 Byte für Ihren "langsamen" Windows-Fall anzeigt. Ich habe erwartet, dass dieses Diagramm nur auf ~ 64.000 Bytes geöffnet ist, da Sie auf 5 Mbit / s beschränkt sind.


0

Dies ist ein faszinierender Thread, der genau zu den Problemen passt, die ich mit Win7 / iperf hatte, um den Durchsatz an langen Fettleitungen zu testen.

Die Lösung für Windows 7 besteht darin, den folgenden Befehl sowohl auf dem iperf-Server als auch auf dem Client auszuführen.

netsh interface tcp set global autotuninglevel = experimental

Hinweis: Bevor Sie dies tun, müssen Sie den aktuellen Status des Autotunings aufzeichnen:

netsh interface tcp show global

Empfangsfenster Auto-Tuning Level: deaktiviert

Führen Sie dann den iperf-Server / -Client an jedem Ende der Pipe aus.

Setzen Sie den Autotuning-Wert nach Ihren Tests zurück:

netsh interface tcp set global autotuninglevel =

   autotuninglevel - One of the following values:
                     disabled: Fix the receive window at its default
                         value.
                     highlyrestricted: Allow the receive window to
                         grow beyond its default value, but do so
                         very conservatively.
                     restricted: Allow the receive window to grow
                         beyond its default value, but limit such
                         growth in some scenarios.
                     normal: Allow the receive window to grow to
                         accomodate almost all scenarios.
                     experimental: Allow the receive window to grow
                         to accomodate extreme scenarios.
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.