Windows TCP Skalowanie okna Zbyt wczesne uderzenie w plateau

50

Scenariusz: Mamy wielu klientów Windows regularnie przesyłających duże pliki (FTP / SVN / HTTP PUT / SCP) na serwery Linux, które są w odległości ~ 100-160 ms. W biurze mamy synchroniczną przepustowość 1 Gb / s, a serwery są instancjami AWS lub fizycznie hostowane w DC w USA.

Początkowy raport był taki, że przesyłanie do nowej instancji serwera było znacznie wolniejsze niż mogłoby być. Znosiło to w testach i z wielu lokalizacji; klienci widzieli stabilne 2-5 Mb / s na hoście z systemów Windows.

Zerwałem się iperf -sna wystąpieniu AWS, a następnie z klienta Windows w biurze:

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

Ta ostatnia liczba może się znacznie różnić w kolejnych testach (Vagaries of AWS), ale zwykle wynosi od 70 do 130 Mb / s, co jest więcej niż wystarczające dla naszych potrzeb. Wiresharking sesji, widzę:

  • iperf -c Windows SYN - Windows 64kb, Skala 1 - Linux SYN, ACK: Windows 14kb, Skala: 9 (* 512) skalowanie okna iperf z domyślnym oknem 64kb
  • iperf -c -w1M Windows SYN - Windows 64kb, Skala 1 - Linux SYN, ACK: Windows 14kb, Skala: 9 skalowanie okna iperf z domyślnym oknem 1 MB

Oczywiście łącze może wytrzymać tak wysoką przepustowość, ale muszę dokładnie ustawić rozmiar okna, aby z niego skorzystać, czego większość aplikacji na świecie nie pozwala mi na to. Uściski dłoni TCP używają tych samych punktów początkowych w każdym przypadku, ale wymuszony skaluje się

I odwrotnie, z klienta Linux w tej samej sieci prosta iperf -c(używając domyślnego systemu 85kb) daje mi:

[  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

Bez użycia siły skaluje się zgodnie z oczekiwaniami. Nie może to być coś w pośrednich przeskokach ani w naszych lokalnych przełącznikach / routerach i wydaje się mieć wpływ na klientów Windows 7 i 8. Przeczytałem wiele przewodników na temat automatycznego dostrajania, ale zazwyczaj dotyczą one całkowitego wyłączenia skalowania, aby obejść zły zestaw sieci domowej.

Czy ktoś może mi powiedzieć, co się tutaj dzieje i dać mi sposób, aby to naprawić? (Najlepiej coś, co mogę trzymać w rejestrze przez GPO.)

Notatki

Instancja AWS Linux, o której mowa, ma następujące ustawienia jądra 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

Użyłem dd if=/dev/zero | ncprzekierowania /dev/nullna końcu serwera, aby wykluczyć iperfi usunąć wszelkie inne możliwe wąskie gardła, ale wyniki są prawie takie same. Testy z ncftp(Cygwin, Native Windows, Linux) są skalowane w podobny sposób, jak powyższe testy Iperf na ich platformach.

Edytować

Zauważyłem tutaj kolejną spójną rzecz, która może być istotna: wprowadź opis zdjęcia tutaj

Jest to pierwsza sekunda powiększenia 1 MB, powiększenie. Możesz zobaczyć Slow Start w akcji, gdy okno skaluje się i bufor staje się większy. Jest wtedy ten niewielki plateau ~ 0.2s dokładnie w punkcie, w którym domyślny test iperf okna spłaszcza się na zawsze. Ten oczywiście skaluje się do znacznie bardziej zawrotnych wysokości, ale ciekawe, że jest taka przerwa w skalowaniu (wartości to 1022 bajtów * 512 = 523264), zanim to zrobi.

Aktualizacja - 30 czerwca.

W odpowiedzi na różne odpowiedzi:

  • Włączanie CTCP - to nie robi różnicy; skalowanie okien jest identyczne. (Jeśli dobrze to rozumiem, to ustawienie zwiększa szybkość powiększania okna przeciążenia, a nie maksymalny rozmiar, jaki może osiągnąć)
  • Włączanie znaczników czasu TCP. - Tu też nie ma zmian.
  • Algorytm Nagle'a - to ma sens i przynajmniej oznacza, że ​​prawdopodobnie mogę zignorować te konkretne blipy na wykresie jako jakiekolwiek oznaki problemu.
  • Pliki pcap: Plik zip dostępny tutaj: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (zanonimizowane za pomocą bittwiste, wyodrębnia do ~ 150 MB, ponieważ istnieje jeden z każdego klienta systemu operacyjnego do porównania)

Aktualizacja 2 - 30 czerwca

O, więc zgodnie z sugestią Kyle'a, włączyłem ctcp i wyłączyłem odciążanie komina: 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

Niestety, nie ma zmiany w przepustowości.

Mam tu jednak pytanie o przyczynę / skutek: wykresy dotyczą wartości RWIN ustawionej w zestawach ACK serwera dla klienta. Czy w przypadku klientów Windows mam rację, myśląc, że Linux nie skaluje tej wartości poza ten najniższy punkt, ponieważ ograniczony CWIN klienta uniemożliwia zapełnienie nawet tego bufora? Czy może istnieć inny powód, dla którego Linux sztucznie ogranicza RWIN?

Uwaga: próbowałem włączyć ECN do cholery; ale bez zmian.

Aktualizacja 3 - 31 czerwca.

Brak zmian po wyłączeniu heurystyki i autotuningu RWIN. Zaktualizowałem sterowniki sieciowe Intel do najnowszej wersji (12.10.28.0) o oprogramowanie, które ujawnia zakładki poprawiania funkcjonalności menedżerów viadevice. Karta to wbudowana karta sieciowa z chipsetem 82579 V - (zamierzam wykonać więcej testów od klientów z Realtek lub innymi dostawcami)

Koncentrując się na chwilę na karcie sieciowej, próbowałem następujących rzeczy (głównie po prostu wykluczając nieoczekiwanych winowajców):

  • Zwiększyć bufory odbioru do 2k z 256 i przesłać bufory do 2k z 512 (oba teraz maksymalnie) - Bez zmian
  • Wyłączono wszystkie odciążanie sumy kontrolnej IP / TCP / UDP. - Brak zmiany.
  • Wyłączone duże wysyłanie odciążenia - Nada.
  • Wyłączono planowanie IPv6, QoS - Nowt.

Aktualizacja 3 - 3 lipca

Próbując wyeliminować stronę serwera Linux, uruchomiłem instancję Server 2012R2 i powtórzyłem testy przy użyciu iperf(cygwin binary) i NTttcp .

Z iperfmusiałem wyraźnie określić -w1mpo obu stronach, zanim połączenie będzie skalowane powyżej ~ 5 Mb / s. (Nawiasem mówiąc, mogłem zostać sprawdzony, a BDP ~ 5 Mb przy opóźnieniu 91 ms to prawie dokładnie 64 kb. Znajdź limit ...)

Pliki binarne ntttcp wykazały teraz takie ograniczenie. Używając ntttcpr -m 1,0,1.2.3.5na serwerze i ntttcp -s -m 1,0,1.2.3.5 -t 10kliencie, widzę znacznie lepszą przepustowość:

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

8 MB / s podnosi to na poziomach, które otrzymywałem z wyraźnie dużymi oknami iperf. Dziwne jednak, że 80 MB w 1273 buforach = bufor 64kB ponownie. Kolejny wireshark pokazuje dobrą, zmienną RWIN wracającą z serwera (współczynnik skali 256), który wydaje się spełniać klient; więc być może ntttcp źle zgłasza okno wysyłania.

Aktualizacja 4 - 3 lipca

Na prośbę @ karyhead wykonałem jeszcze kilka testów i wygenerowałem kilka dodatkowych zdjęć, tutaj: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Dwa kolejne iperfs, oba z systemu Windows na ten sam serwer Linux jak poprzednio (1.2.3.4): Jeden z gniazdem o wielkości 128 kb i domyślnym oknem 64 k (ponownie ogranicza się do ~ 5 Mb / s), a drugi z oknem wysyłania 1 MB i domyślnym gniazdem 8 kb rozmiar. (skaluje się wyżej)
  • Jeden ntttcpślad z tego samego klienta Windows do wystąpienia Server 2012R2 EC2 (1.2.3.5). tutaj przepustowość dobrze się skaluje. Uwaga: NTttcp robi coś dziwnego na porcie 6001, zanim otworzy połączenie testowe. Nie jestem pewien, co się tam dzieje.
  • Jeden ślad danych FTP, przesyłanie 20 MB /dev/urandomdo prawie identycznego hosta Linux (1.2.3.6) przy użyciu Cygwin ncftp. Znowu jest limit. Wzór jest taki sam w przypadku Windows Filezilla.

Zmiana iperfdługości bufora robi oczekiwaną różnicę w wykresie sekwencji czasowej (znacznie więcej pionowych odcinków), ale faktyczna przepustowość pozostaje niezmieniona.

SmallClanger
źródło
11
Rzadki przypadek dobrze zbadanego problemu, którego oczywiście nie ma w dokumentacji. Fajnie - miejmy nadzieję, że ktoś znajdzie rozwiązanie (bo myślę, że ja też mogę to wykorzystać).
TomTom
2
Spróbuj włączyć znaczniki czasu RFC 1323, ponieważ są one domyślnie wyłączone w systemie Windows, a Linux ma je domyślnie włączone. netsh int tcp set global timestamps=enabled
Brian
3
Opóźnienie 200 ms jest prawdopodobnie działającym algorytmem Nagle. Gdy dane są odbierane przez TCP na danym połączeniu, wysyła potwierdzenie tylko wtedy, gdy spełniony jest jeden z następujących warunków: Nie otrzymano potwierdzenia dla poprzedniego odebranego segmentu; Segment jest odbierany, ale żaden inny segment nie dociera w ciągu 200 milisekund dla tego połączenia.
Greg Askew
2
Czy jest jakaś szansa na umieszczenie przechwytywania pakietów od jednego z wolniejszych nadawców?
Kyle Brandt
Zaktualizowałem mojego OP o wyniki tych testów i linki do reprezentatywnych plików przechwytywania.
SmallClanger

Odpowiedzi:

15

Czy próbowałeś włączyć Compound TCP (CTCP) w swoich klientach Windows 7/8.

Proszę przeczytaj:

Zwiększenie wydajności po stronie nadawcy dla transmisji o wysokim BDP

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

...

Algorytmy te działają dobrze dla małych BDP i mniejszych rozmiarów okien odbiorczych. Jednak w przypadku połączenia TCP o dużym rozmiarze okna odbioru i dużym BDP , takim jak replikacja danych między dwoma serwerami zlokalizowanymi w szybkim łączu WAN z czasem przełączania w obie strony 100 ms , algorytmy te nie zwiększają okna wysyłania wystarczająco szybki, aby w pełni wykorzystać przepustowość połączenia .

Aby lepiej wykorzystać przepustowość połączeń TCP w takich sytuacjach, stos TCP / IP nowej generacji zawiera Compound TCP (CTCP). CTCP bardziej agresywnie zwiększa okno wysyłania dla połączeń z dużymi rozmiarami okien odbiorczych i BDP . CTCP próbuje zmaksymalizować przepustowość na tego typu połączeniach poprzez monitorowanie zmian opóźnień i strat. Ponadto CTCP zapewnia, że ​​jego zachowanie nie wpływa negatywnie na inne połączenia TCP.

...

CTCP jest domyślnie włączony na komputerach z systemem Windows Server 2008 i domyślnie wyłączony na komputerach z systemem Windows Vista. Możesz włączyć CTCP za pomocą netsh interface tcp set global congestionprovider=ctcppolecenia. Możesz wyłączyć CTCP za pomocą netsh interface tcp set global congestionprovider=nonepolecenia.

Edytuj 30.06.2014

aby sprawdzić, czy CTCP jest naprawdę „włączony”

> netsh int tcp show global

to znaczy

wprowadź opis zdjęcia tutaj

PO powiedziała:

Jeśli dobrze to zrozumiem, to ustawienie zwiększa szybkość powiększania okna przeciążenia, a nie maksymalny rozmiar, jaki może osiągnąć

CTCP agresywnie zwiększa okno wysyłania

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

Związek TCP

Istniejące algorytmy, które zapobiegają przytłaczaniu sieci równorzędnej TCP przez sieć, nazywane są powolnym startem i unikaniem zatorów. Algorytmy te zwiększają liczbę segmentów, które nadawca może wysłać, zwany oknem wysyłania, podczas początkowego wysyłania danych w połączeniu i odzyskiwania z utraconego segmentu. Powolny start zwiększa okno wysyłania o jeden pełny segment TCP dla każdego odebranego segmentu potwierdzenia (dla TCP w Windows XP i Windows Server 2003) lub dla każdego potwierdzonego segmentu (dla TCP w Windows Vista i Windows Server 2008). Unikanie zatorów zwiększa okno wysyłania o jeden pełny segment TCP dla każdego pełnego okna danych, które jest potwierdzone.

Algorytmy te działają dobrze dla prędkości mediów LAN i mniejszych rozmiarów okien TCP. Jeśli jednak masz połączenie TCP z dużym rozmiarem okna odbiorczego i dużym produktem opóźniającym pasmo (duże pasmo i duże opóźnienie), takim jak replikacja danych między dwoma serwerami znajdującymi się w szybkim łączu WAN z okrążeniem 100 ms Czasami algorytmy te nie zwiększają wystarczająco szybko okna wysyłania, aby w pełni wykorzystać przepustowość połączenia. Na przykład, w przypadku łącza WAN 1 Gb / s (Gb / s) z czasem podróży w obie strony 100 ms (RTT), początkowe zwiększenie okna wysyłania do dużego rozmiaru okna reklamowanego przez odbiornik może potrwać do godziny. odzyskać gdy utracone segmenty.

Aby lepiej wykorzystać przepustowość połączeń TCP w takich sytuacjach, stos TCP / IP nowej generacji zawiera Compound TCP (CTCP). CTCP bardziej agresywnie zwiększa okno wysyłania dla połączeń o dużych rozmiarach okna odbiorczego i dużych produktach opóźniających pasmo. CTCP próbuje zmaksymalizować przepustowość na tego typu połączeniach poprzez monitorowanie zmian opóźnień i strat . CTCP zapewnia również, że jego zachowanie nie wpływa negatywnie na inne połączenia TCP.

W testach przeprowadzonych wewnętrznie w firmie Microsoft czasy tworzenia dużych plików zostały skrócone o prawie połowę w przypadku połączenia 1 Gb / s z 50 ms RTT. Połączenia z większym opóźnieniem przepustowości mogą mieć jeszcze lepszą wydajność. Automatyczne strojenie CTCP i okna odbierania współpracują ze sobą w celu zwiększenia wykorzystania łącza i mogą spowodować znaczny wzrost wydajności w przypadku połączeń produktów o dużym opóźnieniu przepustowości.

Poklepać
źródło
3
Tylko jako uzupełnienie tej odpowiedzi, odpowiednik PowerShell w Server 2012 / Win8.1 jest Set-NetTCPSettingz -CongestionProviderparametrem ... który akceptuje CCTP, DCTCP i domyślną. Klient i serwery Windows używają różnych domyślnych dostawców ograniczeń. technet.microsoft.com/en-us/library/hh826132.aspx
Ryan Ries
Widzę, do czego zmierzasz, ale wydaje się, że nie ma to zastosowania. Ze względu na to pobiegłem 30 minut, iperfa okno nadal nie skalowało się dalej niż ~ 520kb. Coś innego ogranicza CWND, zanim ten agresywny algorytm nie przyniesie żadnych korzyści.
SmallClanger
istnieje stary (już naprawiony) błąd Vista, który przedstawiał tego rodzaju problemy podczas przesyłania protokołów innych niż HTML. Czy Twój problem wygląda dokładnie tak samo podczas przesyłania tego samego pliku przez HTML lub powiedzmy przez FTP?
Pat
@Pat - Tak. Zatwierdzenia SVN (przez HTTP i HTTPS) i transfery FTP do innego systemu na AWS również mają te same ograniczenia.
SmallClanger,
co powiesz na zaporę klienta Win? czy możesz przetestować przy całkowicie wyłączonej zaporze ogniowej? patrz tutaj: ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Pat
12

Wyjaśnienie problemu:

TCP ma dwa okna:

  • Okno odbioru: Ile bajtów pozostało w buforze. Jest to kontrola przepływu narzucona przez odbiornik. Rozmiar okna odbierania można zobaczyć w wireshark, ponieważ składa się on z rozmiaru okna i współczynnika skalowania okna w nagłówku TCP. Obie strony połączenia TCP będą reklamować swoje okno odbioru, ale ogólnie rzecz biorąc, na czym ci zależy, to ten, który odbiera większość danych. W twoim przypadku jest to „serwer”, ponieważ klient przesyła dane na serwer
  • Okno zatoru. Jest to kontrola przepływu narzucona przez Nadawcę. Jest to obsługiwane przez system operacyjny i nie pojawia się w nagłówku TCP. Kontroluje szybkość, z jaką dane będą wysyłane.

W podanym pliku przechwytywania. Widzimy, że bufor odbiorczy nigdy się nie przepełnia:

wprowadź opis zdjęcia tutaj

Moja analiza polega na tym, że nadawca nie wysyła wystarczająco szybko, ponieważ okno wysyłania (inaczej okno kontroli przeciążenia) nie otwiera się wystarczająco, aby zaspokoić RWIN odbiornika. Krótko mówiąc, odbiorca mówi „Daj mi więcej”, a gdy Windows jest nadawcą, nie wysyła wystarczająco szybko.

Dowodzi tego fakt, że na powyższym wykresie RWIN pozostaje otwarty, a przy czasie podróży w obie strony 0,09 sekundy i RWIN wynoszącym ~ 500 000 bajtów możemy spodziewać się maksymalnej przepustowości zgodnie z iloczynem opóźnienia przepustowości (500000 /0.09) * 8 = ~ 42 Mbit / s (i dostajesz tylko około ~ 5 w swojej wygranej do przechwytywania w systemie Linux).

Jak to naprawić?

Nie wiem interface tcp set global congestionprovider=ctcpbrzmi jak właściwa rzecz do zrobienia, ponieważ zwiększyłoby to okno wysyłania (co jest innym terminem dla okna przeciążenia). Powiedziałeś, że to nie działa. Aby się upewnić:

  1. Czy zrestartowałeś się po włączeniu tego?
  2. Czy komin jest włączony? Jeśli to możliwe, spróbuj wyłączyć to jako eksperyment. Nie wiem, co dokładnie zostaje odciążone, gdy ta funkcja jest włączona, ale jeśli kontrolowanie okna wysyłania jest jednym z nich, być może dostawca przeciążenia nie działa, gdy jest włączony ... Po prostu zgaduję ...
  3. Myślę też, że może to być wcześniejsza wersja systemu Windows 7, ale możesz spróbować dodać i bawić się dwoma kluczami rejestru o nazwie DefaultSendWindow i DefaultReceiveWindow w parametrach HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD. Jeśli te w ogóle działają, prawdopodobnie masz wyłączone ctcp.
  4. Jeszcze jedna próba, spróbuj sprawdzić netsh interface tcp show heuristics. Myślę, że może to być RWIN, ale nie mówi, więc może graj z wyłączaniem / włączaniem, jeśli wpłynie to na okno wysyłania.
  5. Upewnij się również, że sterowniki są aktualne na kliencie testowym. Może coś się popsuło.

Na początek spróbowałbym wszystkich tych eksperymentów ze wszystkimi funkcjami odciążania, aby wyeliminować możliwość, że sterowniki sieciowe dokonują pewnych przeróbek / modyfikacji rzeczy (miej oko na procesor, gdy odciążanie jest wyłączone). Struktura TCP_OFFLOAD_STATE_DELEGATED wydaje się co najmniej sugerować, że odciążenie CWnd jest co najmniej możliwe.

Kyle Brandt
źródło
2
Zgłosiłem twoją „odpowiedź”, ponieważ twoja nie jest odpowiedzią; Natychmiast zostałem odrzucony; teraz widzę, jak „ludzie” głosują na twoją „odpowiedź bez odpowiedzi” ... naprawdę zabawne
Pat
1
@Pat: Możesz także kliknąć liczbę głosów, aby zobaczyć podział Upvotes / Downvotes. Obecnie nie ma żadnych ocen negatywnych na swoją odpowiedź. Moja odpowiedź nie rozwiązuje jego problemu (ale nie ma jeszcze odpowiedzi), wyjaśnia i lokalizuje problem (mam nadzieję, że poprawnie!), Co jest ważnym krokiem w rozwiązywaniu problemów.
Kyle Brandt
@ Kyle Brandt, jeśli akceptujesz swoją, nie jest odpowiedzią Zastanawiam się, dlaczego nie jest ona „automatycznie” usuwana bez dalszego rozpatrywania? i mylisz się; Otrzymałem głos negatywny (bez głosowania) „jak tylko”, kiedy zgłosiłem twoją „odpowiedź”; ten nie został jeszcze usunięty. Wygląda na to, że grasz tutaj według „specjalnych” zasad.
Pat
1
@Pat Jeśli to pomaga, brak odpowiedzi Kyle'a był niezwykle pomocny. Teraz mam jaśniejsze pojęcie o tym, które bufory są ograniczone i czuję, że w rezultacie jestem trochę bliżej właściwego rozwiązania. Czasami pytania takie jak to może być wspólny wysiłek, że z odrobiną rozsądne edycji może stać się właściwą Q i właściwa .
SmallClanger,
@SmallClanger z całym szacunkiem, SF ma zestaw zasad, których powinni przestrzegać wszyscy jego użytkownicy, w tym Kyle Brandt; jeśli nie jest odpowiedzią, musi zostać skasowany lub przeniesiony jako komentarz, bez względu na to, ilu ma przyjaciół w klubie „moderatorów”.
Pat
5

@Pat i @Kyle mają tutaj świetne informacje. Zdecydowanie zwróć uwagę na wyjaśnienia @ Kyle'a dotyczące odbierania i wysyłania okien przez TCP, myślę, że było w tym trochę zamieszania. Aby jeszcze bardziej pomylić sprawy, iperf używa terminu „okno TCP” z -wustawieniem, które jest rodzajem dwuznacznym w odniesieniu do okna odbierania, wysyłania lub ogólnego przesuwanego okna. W rzeczywistości ustawia bufor wysyłania gniazda dla -cinstancji (klienta), a bufor odbierania gniazda dla -sinstancji (serwera). W 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 ));
}

Jak wspomina Kyle, problem nie dotyczy okna odbierania w Linux-ie, ale nadawca nie otwiera wystarczająco okna wysyłania. Nie chodzi o to, że nie otwiera się wystarczająco szybko, po prostu ogranicza się do 64k.

Domyślny rozmiar bufora gniazda w systemie Windows 7 to 64k. Oto, co dokumentacja mówi o rozmiarze bufora gniazda w stosunku do przepustowości w MSDN

Wysyłając dane przez połączenie TCP za pomocą gniazd Windows, ważne jest, aby zachować wystarczającą ilość danych zaległych (wysłanych, ale jeszcze nie potwierdzonych) w TCP, aby osiągnąć najwyższą przepustowość. Idealna wartość ilości danych pozostających do osiągnięcia najlepszej przepustowości dla połączenia TCP nazywa się idealną wielkością zaległości wysyłania (ISB). Wartość ISB jest funkcją iloczynu opóźnienia przepustowości połączenia TCP i reklamowanego okna odbioru odbiornika (i częściowo ilości przeciążenia w sieci).

Ok, bla bla bla, teraz zaczynamy:

Aplikacje, które wykonują jedno blokujące lub nieblokujące żądanie wysyłania na raz, zwykle polegają na wewnętrznym buforowaniu wysyłania przez Winsock, aby osiągnąć przyzwoitą przepustowość. Limit bufora wysyłania dla danego połączenia jest kontrolowany przez opcję gniazda SO_SNDBUF. W przypadku metody wysyłania blokującej i nieblokującej limit bufora wysyłania określa, ile danych jest przeterminowanych w TCP . Jeśli wartość ISB dla połączenia jest większa niż limit bufora wysyłania, przepustowość osiągnięta na połączeniu nie będzie optymalna.

Średnia przepustowość ostatniego testu iperf przy użyciu okna 64k wynosi 5,8 Mb / s. To z Statystyki> Podsumowanie w Wireshark, który liczy wszystkie bity. Prawdopodobnie iperf liczy przepustowość danych TCP, która wynosi 5,7 Mb / s. Tę samą wydajność widzimy również w teście FTP, ~ 5,6 Mb / s.

Teoretyczna przepustowość przy buforze wysyłania 64 tys. I RTT 91 ms wynosi .... 5,5 Mb / s. Wystarczająco blisko dla mnie.

Jeśli spojrzymy na twój test Iperf dla okna 1 MB, prędkość wynosi 88,2 Mb / s (86,2 Mb / s tylko dla danych TCP). Teoretyczna przepustowość z oknem 1 MB wynosi 87,9 Mb / s. Znowu wystarczająco blisko do pracy rządu.

Pokazuje to, że bufor gniazda wysyłania bezpośrednio kontroluje okno wysyłania, a w połączeniu z oknem odbioru z drugiej strony kontroluje przepustowość. Reklamowane okno odbioru ma miejsce, więc odbiorca nie ogranicza nas.

Poczekaj, a co z tym biznesem dostrajania? Czy system Windows 7 nie obsługuje tych rzeczy automatycznie? Jak już wspomniano, system Windows obsługuje automatyczne skalowanie okna odbierania, ale może także dynamicznie obsługiwać bufor wysyłania. Wróćmy do strony MSDN:

Dynamiczne buforowanie wysyłania dla TCP zostało dodane w Windows 7 i Windows Server 2008 R2. Domyślnie dynamiczne buforowanie wysyłania dla TCP jest włączone, chyba że aplikacja ustawi opcję gniazda SO_SNDBUF w gnieździe strumienia.

iperf używa SO_SNDBUFtej -wopcji, więc dynamiczne buforowanie wysyłania byłoby wyłączone. Jednak jeśli nie używasz, -wto nie używa SO_SNDBUF. Dynamiczne buforowanie wysyłania powinno być domyślnie włączone, ale możesz sprawdzić:

netsh winsock show autotuning

Dokumentacja mówi, że możesz to wyłączyć za pomocą:

netsh winsock set autotuning off

Ale to nie działało dla mnie. Musiałem dokonać zmiany rejestru i ustawić to na 0:

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

Nie sądzę, że wyłączenie tego pomoże; to tylko informacja dla ciebie.

Dlaczego skalowanie bufora wysyłania nie przekracza domyślnego 64k podczas wysyłania danych do Linux-a z dużą ilością miejsca w oknie odbioru? Świetne pytanie. Jądra systemu Linux mają również stos TCP do autotuningu. Podobnie jak T-Pain i Kanye wspólnie grający duet autotune, może to nie brzmieć dobrze. Być może jest jakiś problem z tymi dwoma automatycznymi tuningami stosów TCP rozmawiającymi ze sobą.

Inna osoba miała problem podobny do twojego i była w stanie go naprawić za pomocą edycji rejestru, aby zwiększyć domyślny rozmiar bufora wysyłania. Niestety, wydaje się, że to już nie działa, a przynajmniej nie działało dla mnie, kiedy próbowałem.

W tym momencie myślę, że jasne jest, że czynnikiem ograniczającym jest rozmiar bufora wysyłania na hoście Windows. Biorąc pod uwagę, że nie wydaje się dynamicznie prawidłowo rosnąć, co robi dziewczyna?

Możesz:

  • Użyj aplikacji, które pozwalają ustawić bufor wysyłania, tj. Opcję okna
  • Użyj lokalnego serwera proxy Linux
  • Używać zdalnego serwera proxy Windows?
  • Otwórz skrzynkę z Microsofhahahahahahaha
  • piwo

Oświadczenie: Spędziłem wiele godzin badając to i jest to zgodne z moją najlepszą wiedzą i Google-Fu. Ale nie przysięgałbym na grób mojej matki (ona wciąż żyje).

karyhead
źródło
Wkład Fantasic; Dziękuję Ci. Korzystam z iperf 2.0.4, eksperymentuję z ustawieniami i aktualizuję OP również nowymi ograniczeniami.
SmallClanger,
Ok, zaktualizowałem moją „odpowiedź” w oparciu o więcej badań i wasze ostatnie testy
karyhead
Dzięki. Przynajmniej częściowo miło jest wiedzieć, że nie oszaleję. Przeczytałem kilka blogów / wątków z dni XP / 2003, które zalecają te ustawienia rejestru, ale zostały one napisane przed Vista / 2008 i jestem prawie pewien, że są ignorowane w Vista. Myślę, że faktycznie podniosę bilet ze stwardnieniem
rozsianym
1
Przydatnym narzędziem, na które natknąłem się w moich badaniach, był tcpanalyzer.exe w zestawie SDK ( microsoft.com/en-us/download/details.aspx?id=8279 ). Jest to graficzna sieć, w której możesz wybrać pojedyncze połączenie i uzyskać statystyki TCP, takie jak RTT, cwnd, retransmisje itp. Mógłbym sprawić, aby cwnd otworzył się znacznie powyżej rozmiaru bufora wysyłania, ale tput się nie zwiększył i wireshark zweryfikował że nadal jest wysyłany bufor ograniczony.
karyhead
1
Znalazłem komentarze na kilku forach dotyczące poleceń „netsh”, które nie działają zgodnie z reklamą w 7/8, a ludzie zmuszeni są do ręcznego wprowadzania odpowiednich wpisów rejestru; Zastanawiam się, czy coś takiego może się dziać z opcją CTCP.
Pat
4

Po dostrojeniu stosu TCP może nadal występować wąskie gardło w warstwie Winsock. Przekonałem się, że konfiguracja Winsock (pomocniczego sterownika funkcji w rejestrze) ma ogromne znaczenie dla prędkości wysyłania (wypychania danych do serwera) w systemie Windows 7. Microsoft potwierdził błąd w autotuningu TCP dla gniazd nieblokujących - tylko rodzaj gniazda używanego przez przeglądarki ;-)

Dodaj klucz DWORD dla DefaultSendWindow i ustaw go na BDP lub wyższy. Używam 256000.

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

Zmiana ustawienia Winsock do pobierania może pomóc - dodaj klucz dla DefaultReceiveWindow.

Możesz eksperymentować z różnymi ustawieniami poziomu gniazda, używając Fiddler Proxy i poleceń, aby dostosować rozmiary bufora gniazda klienta i serwera:

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
LeslieM
źródło
Świetny dodatkowy kawałek informacji. Czy masz przypadkiem link referencyjny do błędu MS?
SmallClanger
3

Po przeczytaniu wszystkich analiz zawartych w odpowiedziach problem ten brzmi bardzo podobnie do systemu Windows 7 / 2008R2 lub Windows 6.1

Stos sieci (TCP / IP i Winsock) w systemie Windows 6.1 był strasznie wadliwy i zawierał wiele błędów i problemów z wydajnością, które Microsoft ostatecznie rozwiązał przez wiele lat poprawek od pierwszej wersji 6.1.

Najlepszym sposobem na zastosowanie tych poprawek jest ręczne przeglądanie wszystkich odpowiednich stron w witrynie support.microsoft.com oraz ręczne żądanie i pobieranie wersji LDR poprawek stosu sieciowego (jest ich wiele.

Aby znaleźć odpowiednie poprawki, musisz użyć www.bing.com z następującym zapytaniem site:support.microsoft.com 6.1.7601 tcpip.sys

Musisz także zrozumieć, jak działają zestawy poprawek LDR / GDR w systemie Windows 6.1

Zwykle utrzymywałem własną listę poprawek LDR (nie tylko poprawki stosu sieciowego) dla Windows 6.1, a następnie proaktywnie stosowałem te poprawki na dowolnym serwerze / kliencie Windows 6.1, z którym się spotkałem. Sprawdzanie dostępności nowych poprawek LDR było bardzo czasochłonne.

Na szczęście Microsoft zaprzestał stosowania poprawek LDR w nowszych wersjach systemu operacyjnego, a poprawki są teraz dostępne za pośrednictwem usług automatycznych aktualizacji firmy Microsoft.

AKTUALIZACJA : Tylko jeden przykład wielu błędów sieciowych w Windows7SP1 - https://support.microsoft.com/en-us/kb/2675785

AKTUALIZACJA 2 : Oto kolejna poprawka, która dodaje przełącznik netsh, aby wymusić skalowanie okna po drugiej retransmisji pakietu SYN (domyślnie skalowanie okna jest wyłączone po ponownym przesłaniu 2 pakietów SYN) https://support.microsoft.com/en- us / kb / 2780879

Christoph Wegener
źródło
Dzięki Christoph; kilka bardzo interesujących nowych informacji na ten temat oraz że „funkcja” retransmisji SYN jest bardzo dziwna; W ogóle nie widzę celu projektowego. (Może jakiś rodzaj prymitywnego wykrywania zatorów?). Wszystkie oryginalne testy zostały wykonane na Win7SP1; niedługo będziemy testować Win10 i to ode mnie zależy, aby ponownie uruchomić większość z nich, aby zobaczyć, jak sobie radzi.
SmallClanger,
Z którą gałęzią systemu Windows 10 będziesz testować? Nie mam jeszcze doświadczenia ze stosem sieci w Windows 10.
Christoph Wegener
Naszym celem jest Enterprise 1511.
SmallClanger,
Widzę. Wybór systemu Windows 10 jest dość trudny, ponieważ jest ich tak wiele. Natrafiłem już na jeden problem z Windows 10, w którym nie mogłem użyć określonej funkcji, ponieważ byłem w oddziale LTSB. Chciałbym, aby Microsoft zmniejszył ogólną liczbę dostępnych gałęzi i zamiast tego ulepszył dokumentację o tym, jakie poprawki i funkcje są zawarte w każdej kompilacji ...
Christoph Wegener,
1

Widzę, że jest to nieco starszy post, ale może pomóc innym.

Krótko mówiąc, musisz włączyć „Automatyczne dostrajanie okna odbioru”:

netsh int tcp set global autotuninglevel=normal

CTCP nic nie znaczy bez powyższej opcji.

Jeśli wyłączysz „Automatyczne dostrajanie okna odbioru”, utkniesz w rozmiarze pakietu 64 KB, co ma negatywny wpływ na długie RTT w połączeniach szerokopasmowych. Możesz także eksperymentować z opcją „ograniczona” i „wysoce ograniczona”.

Bardzo dobra referencja: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html

spricer
źródło
1

Wystąpił podobny problem z klientami Windows (Windows 7). Przeszedłem przez większość debugowania, przez które przeszliście, wyłączając algorytm Nagle, odciążanie komina TCP i mnóstwo innych zmian ustawień związanych z TCP. Żadne z nich nie miało żadnego efektu.

To, co w końcu to naprawiło, to modyfikacja domyślnego okna wysyłania w rejestrze usługi AFD. Problem wydaje się być związany z plikiem afd.sys. Przetestowałem kilka klientów, niektóre wykazywały powolne ładowanie, a niektóre nie, ale wszystkie były komputerami z systemem Windows 7. Maszyny wykazujące wolne działanie miały tę samą wersję AFD.sys. Obejście rejestru jest wymagane w przypadku komputerów z niektórymi wersjami pliku AFD.sys (przepraszam, nie pamiętaj wersji #).

HKLM \ CurrentControlSet \ Services \ AFD \ Parameters

Dodaj - DWORD - DefaultSendWindow

Wartość - dziesiętna - 1640960

Znalazłem tutaj tę wartość: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Myślę, że aby użyć właściwej wartości, powinieneś ją obliczyć, używając:

na przykład. Przesyłanie reklamowane: 15 Mb / s = 15 000 Kb / s

(15000/8) * 1024 = 1920000

Z tego, co rozumiem, oprogramowanie klienckie powinno zasadniczo zastępować to ustawienie w rejestrze, ale jeśli nie, używana jest wartość domyślna i najwyraźniej wartość domyślna jest bardzo niska w niektórych wersjach pliku AFD.sys.

Zauważyłem, że głównie produkty MS miały problem z powolnym przesyłaniem (IE, Mini-redirector (WebDAV), FTP za pośrednictwem Eksploratora Windows itp.). Podczas korzystania z oprogramowania innych firm (np. Filezilla) nie miałem takich samych spowolnień .

AFD.sys wpływa na wszystkie połączenia Winsock, więc ta poprawka powinna mieć zastosowanie do FTP, HTTP, HTTPS itp.

Ponadto, ta poprawka została gdzieś wymieniona powyżej, więc nie chcę jej przypisywać, jeśli zadziała ona dla kogokolwiek, jednak w tym wątku było tyle informacji, że obawiałem się, że mogła zostać poprawiona.

jjspierx
źródło
0

Cóż, sam spotkałem się z podobną sytuacją (moje pytanie tutaj ) i ostatecznie musiałem wyłączyć heurystykę skalowania TCP, ręcznie ustawić profil autotuningu i włączyć CTCP:

# 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. 
André Fernandes
źródło
0

Nie mam wystarczającej liczby punktów do skomentowania, więc zamiast tego opublikuję „odpowiedź”. Mam coś, co wydaje się być podobnym / identycznym problemem (patrz pytanie o awarię serwera tutaj ). Moim (i prawdopodobnie twoim) problemem jest bufor wysyłania klienta iperf w systemie Windows. Nie przekracza 64 KB. System Windows ma dynamicznie powiększać bufor, gdy proces nie określa go wyraźnie. Ale ten dynamiczny wzrost nie ma miejsca.

Nie jestem pewien, czy twój wykres skalowania okna pokazuje okno otwierające się do 500 000 bajtów dla twojego „powolnego” przypadku Windows. Spodziewałem się, że ten wykres będzie otwarty tylko na ~ 64 000 bajtów, biorąc pod uwagę, że jesteś ograniczony do 5 Mb / s.

Chris Stankevitz
źródło
0

To fascynujący wątek i dokładnie pasuje do problemów, które miałem przy użyciu Win7 / iperf do testowania przepustowości na długich grubych rurach.

Rozwiązaniem dla Windows 7 jest wykonanie następującego polecenia zarówno na serwerze iperf ORAZ na kliencie.

netsh interface tcp set global autotuninglevel = eksperymentalny

Uwaga: zanim to zrobisz, pamiętaj o zapisaniu aktualnego stanu autostrojenia:

netsh interface tcp show global

Poziom automatycznego dostrajania okna odbioru: wyłączony

Następnie uruchom serwer / klient iperf na każdym końcu potoku.

Zresetuj wartość autostrojenia po testach:

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.
Wicksee
źródło