Windows TCP Window Scaling Colpire plateau troppo presto


50

Scenario: abbiamo un certo numero di client Windows che caricano regolarmente file di grandi dimensioni (FTP / SVN / HTTP PUT / SCP) su server Linux che distano ~ 100-160 ms. Abbiamo una larghezza di banda sincrona di 1 Gbit / s in ufficio e i server sono istanze AWS o ospitati fisicamente in DC statunitensi.

Il rapporto iniziale era che i caricamenti su una nuova istanza del server erano molto più lenti di quanto potessero essere. Ciò si è sviluppato durante i test e da più posizioni; i client vedevano stabili 2-5 Mbit / s sull'host dai loro sistemi Windows.

Sono uscito iperf -ssu un'istanza AWS e poi da un client Windows in ufficio:

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

Quest'ultima cifra può variare in modo significativo nei test successivi (Vagaries of AWS) ma di solito è compresa tra 70 e 130 Mbit / s, il che è più che sufficiente per le nostre esigenze. Wiresharking la sessione, posso vedere:

  • iperf -c Windows SYN - Window 64kb, Scala 1 - Linux SYN, ACK: Window 14kb, Scala: 9 (* 512) ridimensionamento della finestra iperf con Windows 64kb predefinito
  • iperf -c -w1M Windows SYN - Windows 64kb, Scala 1 - Linux SYN, ACK: Finestra 14kb, Scala: 9 ridimensionamento della finestra iperf con la finestra predefinita da 1 MB

Chiaramente il collegamento può sostenere questo elevato throughput, ma devo esplicitamente impostare le dimensioni della finestra per farne uso, cosa che la maggior parte delle applicazioni del mondo reale non mi consente di fare. Gli handshake TCP usano gli stessi punti di partenza in ogni caso, ma quello forzato si ridimensiona

Viceversa, da un client Linux sulla stessa rete un diritto iperf -c(usando il 85kb predefinito di sistema) mi dà:

[  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

Senza forzature, si ridimensiona come previsto. Questo non può essere qualcosa negli hop intermedi o nei nostri switch / router locali e sembra influenzare allo stesso modo i client Windows 7 e 8. Ho letto molte guide sull'auto-tuning, ma in genere riguardano la disabilitazione del ridimensionamento per aggirare il terribile kit di reti domestiche.

Qualcuno può dirmi cosa sta succedendo qui e darmi un modo per risolverlo? (Preferibilmente qualcosa su cui posso aderire al registro tramite GPO.)

Appunti

L'istanza AWS Linux in questione ha le seguenti impostazioni del kernel applicate in 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

Ho usato il dd if=/dev/zero | ncreindirizzamento a /dev/nullfine server per escludere iperfe rimuovere eventuali altri colli di bottiglia, ma i risultati sono più o meno gli stessi. I test con ncftp(Cygwin, Native Windows, Linux) si adattano più o meno allo stesso modo dei precedenti test iperf sulle rispettive piattaforme.

modificare

Ho notato un'altra cosa coerente qui che potrebbe essere rilevante: inserisci qui la descrizione dell'immagine

Questo è il primo secondo dell'acquisizione da 1 MB, ingrandito. Puoi vedere l' Avvio lento in azione mentre la finestra si ingrandisce e il buffer si ingrandisce. C'è quindi questo piccolo altopiano di ~ 0,2s esattamente nel punto in cui il test iperf della finestra predefinito si appiattisce per sempre. Questo ovviamente scala ad altezze molto più vertiginose, ma è curioso che ci sia questa pausa nel ridimensionamento (i valori sono 1022 byte * 512 = 523264) prima di farlo.

Aggiornamento - 30 giugno.

Seguendo le varie risposte:

  • Abilitazione CTCP - Questo non fa differenza; il ridimensionamento delle finestre è identico. (Se lo capisco correttamente, questa impostazione aumenta la velocità con cui la finestra di congestione viene ingrandita anziché la dimensione massima che può raggiungere)
  • Abilitazione dei timestamp TCP. - Nessun cambiamento qui neanche.
  • Algoritmo di Nagle - Questo ha senso e almeno significa che probabilmente posso ignorare quel particolare blip nel grafico come qualsiasi indicazione del problema.
  • file pcap: file zip disponibile qui: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (reso anonimo con bittwiste, estratto da ~ 150 MB in quanto è presente uno per ciascun client OS per il confronto)

Aggiornamento 2 - 30 giugno

O, quindi a seguito dell'op su suggerimento di Kyle, ho abilitato ctcp e disabilitato lo scarico del camino: parametri globali TCP

----------------------------------------------
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

Ma purtroppo, nessun cambiamento nel throughput.

Qui ho una domanda causa / effetto: I grafici sono del valore RWIN impostato negli ACK del server al client. Con i client Windows, ho ragione nel pensare che Linux non ridimensiona questo valore oltre quel punto basso perché il CWIN limitato del client impedisce persino il riempimento di quel buffer? Potrebbe esserci qualche altra ragione per cui Linux sta limitando artificialmente RWIN?

Nota: ho provato ad attivare ECN per l'inferno; ma nessun cambiamento, lì.

Aggiornamento 3 - 31 giugno.

Nessuna modifica a seguito della disabilitazione dell'euristica e dell'autotuning RWIN. Hanno aggiornato i driver di rete Intel alla versione più recente (12.10.28.0) con un software che espone le modifiche delle funzionalità tramite le schede del gestore dispositivi. La scheda è una scheda di rete integrata a chipset da 82579 V - (farò altri test da parte di clienti con realtek o altri fornitori)

Concentrandomi sulla scheda di rete per un momento, ho provato quanto segue (principalmente escludendo improbabili colpevoli):

  • Aumenta i buffer di ricezione a 2k da 256 e trasmetti i buffer a 2k da 512 (entrambi ora al massimo) - Nessuna modifica
  • Disabilitato tutto l'offload del checksum IP / TCP / UDP. - Nessun cambiamento.
  • Offload invio grande disabilitato - Nada.
  • Disattivato IPv6, programmazione QoS - Nowt.

Aggiornamento 3 - 3 luglio

Nel tentativo di eliminare il lato server Linux, ho avviato un'istanza di Server 2012R2 e ripetuto i test utilizzando iperf(cygwin binary) e NTttcp .

Con iperf, ho dovuto specificare esplicitamente -w1msu entrambi i lati prima che la connessione si ridimensionasse oltre ~ 5Mbit / s. (Per inciso, potrei essere controllato e il BDP di ~ 5Mbit a 91ms di latenza è quasi esattamente 64kb. Trova il limite ...)

I binari ntttcp hanno mostrato ora tale limitazione. Usando ntttcpr -m 1,0,1.2.3.5sul server e ntttcp -s -m 1,0,1.2.3.5 -t 10sul client, posso vedere un throughput molto migliore:

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 lo mette ai livelli che stavo ottenendo con finestre esplicitamente grandi in iperf. Stranamente, tuttavia, 80 MB in buffer 1273 = di nuovo un buffer da 64 kB. Un ulteriore wirehark mostra un RWIN buono e variabile che ritorna dal server (fattore di scala 256) che il client sembra soddisfare; quindi forse ntttcp sta segnalando erroneamente la finestra di invio.

Aggiornamento 4 - 3 luglio

Su richiesta di @ karyhead, ho fatto qualche altro test e generato altre acquisizioni, qui: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Altri due iperfs, entrambi da Windows allo stesso server Linux di prima (1.2.3.4): uno con una dimensione socket 128k e una finestra predefinita 64k (limitata a ~ 5Mbit / s di nuovo) e uno con una finestra di invio 1MB e socket predefinito 8kb taglia. (scala superiore)
  • Una ntttcptraccia dallo stesso client Windows a un'istanza Server 2012R2 EC2 (1.2.3.5). qui, il throughput si ridimensiona bene. Nota: NTttcp fa qualcosa di strano sulla porta 6001 prima di aprire la connessione di prova. Non sono sicuro di cosa stia succedendo lì.
  • Una traccia di dati FTP, caricando 20 MB su /dev/urandomun host Linux quasi identico (1.2.3.6) usando Cygwin ncftp. Ancora una volta il limite è lì. Il modello è più o meno lo stesso con Windows Filezilla.

La modifica della iperflunghezza del buffer fa la differenza prevista per il grafico della sequenza temporale (molte più sezioni verticali), ma la velocità effettiva rimane invariata.


11
Un raro esempio di un problema ben studiato che non è ovviamente nella documentazione. Bello - speriamo che qualcuno trovi una soluzione (perché in qualche modo penso di poter usare anche quella).
TomTom,

2
Prova ad attivare i timestamp RFC 1323 poiché sono disabilitati per impostazione predefinita in Windows mentre Linux li ha abilitati per impostazione predefinita). netsh int tcp set global timestamps=enabled
Brian,

3
Il ritardo di 200 ms è probabilmente l'algoritmo Nagle in azione. Quando i dati vengono ricevuti da TCP su una particolare connessione, invia un riconoscimento solo se si verifica una delle seguenti condizioni: Non è stato inviato alcun riconoscimento per il segmento precedente ricevuto; Viene ricevuto un segmento, ma nessun altro segmento arriva entro 200 millisecondi per quella connessione.
Greg Askew,

2
Qualche possibilità di mettere da parte alcuni pacchetti di acquisizione da uno dei mittenti più lenti da qualche parte?
Kyle Brandt,

Ho aggiornato il mio PO con i risultati di questi test e collegamenti a file di acquisizione rappresentativi.
SmallClanger,

Risposte:


15

Hai provato ad abilitare Compound TCP (CTCP) nei tuoi client Windows 7/8.

Si prega di leggere:

Aumento delle prestazioni sul lato mittente per la trasmissione ad alto BDP

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

...

Questi algoritmi funzionano bene per BDP piccoli e dimensioni di finestre di ricezione inferiori. Tuttavia, quando si dispone di una connessione TCP con una finestra di ricezione di grandi dimensioni e un BDP di grandi dimensioni , come la replica di dati tra due server situati su un collegamento WAN ad alta velocità con un tempo di andata e ritorno di 100 ms , questi algoritmi non aumentano la finestra di invio abbastanza veloce da utilizzare completamente la larghezza di banda della connessione .

Per utilizzare meglio la larghezza di banda delle connessioni TCP in queste situazioni, lo stack TCP / IP di nuova generazione include Compound TCP (CTCP). CTCP aumenta in modo più aggressivo la finestra di invio per le connessioni con grandi finestre di ricezione e BDP . CTCP tenta di massimizzare la produttività su questi tipi di connessioni monitorando le variazioni e le perdite di ritardo. Inoltre, CTCP garantisce che il suo comportamento non influisca negativamente su altre connessioni TCP.

...

CTCP è abilitato per impostazione predefinita nei computer che eseguono Windows Server 2008 e disabilitato per impostazione predefinita nei computer che eseguono Windows Vista. È possibile abilitare CTCP con il netsh interface tcp set global congestionprovider=ctcpcomando. È possibile disabilitare CTCP con il netsh interface tcp set global congestionprovider=nonecomando.

Modifica il 30/06/2014

per vedere se CTCP è davvero "attivo"

> netsh int tcp show global

vale a dire

inserisci qui la descrizione dell'immagine

PO ha detto:

Se lo capisco correttamente, questa impostazione aumenta la velocità con cui la finestra di congestione viene ingrandita anziché la dimensione massima che può raggiungere

CTCP aumenta in modo aggressivo la finestra di invio

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

TCP composto

Gli algoritmi esistenti che impediscono a un peer TCP di invio di travolgere la rete sono noti come avvio lento ed prevenzione della congestione. Questi algoritmi aumentano la quantità di segmenti che il mittente può inviare, nota come finestra di invio, durante l'invio iniziale dei dati sulla connessione e il recupero da un segmento perso. L'avvio lento aumenta la finestra di invio di un segmento TCP completo per ciascun segmento di riconoscimento ricevuto (per TCP in Windows XP e Windows Server 2003) o per ciascun segmento riconosciuto (per TCP in Windows Vista e Windows Server 2008). L'eliminazione della congestione aumenta la finestra di invio di un segmento TCP completo per ciascuna finestra di dati riconosciuta.

Questi algoritmi funzionano bene per velocità dei supporti LAN e dimensioni di finestre TCP più piccole. Tuttavia, quando si dispone di una connessione TCP con una finestra di ricezione di grandi dimensioni e un prodotto con ritardo della larghezza di banda elevato (larghezza di banda elevata e ritardo elevato), come la replica di dati tra due server situati su un collegamento WAN ad alta velocità con un round trip di 100 ms tempo, questi algoritmi non aumentano la finestra di invio abbastanza velocemente da utilizzare completamente la larghezza di banda della connessione. Ad esempio, su un collegamento WAN da 1 Gigabit al secondo (Gbps) con un tempo di andata e ritorno (RTT) di 100 ms, può richiedere fino a un'ora prima che la finestra di invio aumenti alle dimensioni della finestra di grandi dimensioni pubblicizzate dal ricevitore e per recuperare quando ci sono segmenti persi.

Per utilizzare meglio la larghezza di banda delle connessioni TCP in queste situazioni, lo stack TCP / IP di nuova generazione include Compound TCP (CTCP). CTCP aumenta in modo più aggressivo la finestra di invio per le connessioni con grandi finestre di ricezione e grandi prodotti con ritardo di larghezza di banda. CTCP tenta di massimizzare la produttività su questi tipi di connessioni monitorando le variazioni e le perdite di ritardo . CTCP garantisce inoltre che il suo comportamento non influisca negativamente su altre connessioni TCP.

Nei test eseguiti internamente presso Microsoft, i tempi di backup dei file di grandi dimensioni sono stati ridotti di quasi la metà per una connessione da 1 Gbps con un RTT da 50 ms. Le connessioni con un prodotto con ritardo di larghezza di banda maggiore possono offrire prestazioni ancora migliori. CTCP e la finestra di sintonizzazione automatica lavorano insieme per un maggiore utilizzo dei collegamenti e possono comportare miglioramenti sostanziali delle prestazioni per connessioni di prodotti con grandi ritardi di larghezza di banda.


3
Proprio come complemento a questa risposta, l'equivalente Powershell in Server 2012 / Win8.1 è Set-NetTCPSettingcon il -CongestionProviderparametro ... che accetta CCTP, DCTCP e Default. Client e server Windows utilizzano provider di congestione predefiniti diversi. technet.microsoft.com/en-us/library/hh826132.aspx
Ryan Ries

Vedo a cosa stai arrivando, ma non sembra applicabile. Per il bene, ho funzionato per 30 minuti iperfe la finestra non è mai stata ridimensionata oltre ~ 520kb. Qualcos'altro sta limitando il CWND prima che questo algoritmo aggressivo possa mostrare alcun vantaggio.
SmallClanger,

c'è un vecchio bug (già corretto) di Vista che presentava questo tipo di problemi durante la trasmissione di protocolli non HTML. Il tuo problema sembra esattamente lo stesso quando trasferisci lo stesso file tramite HTML o diciamo tramite FTP?
Pat

@Pat - Lo fa. Anche i commit SVN (via HTTP e HTTPS) e i trasferimenti FTP su un altro sistema su AWS presentano gli stessi limiti.
SmallClanger,

che ne dici di Win client firewall? puoi testare con il firewall completamente spento? vedi qui: ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Pat

12

Chiarire il problema:

TCP ha due finestre:

  • La finestra di ricezione: quanti byte rimangono nel buffer. Questo è il controllo di flusso imposto dal ricevitore. Puoi vedere la dimensione della finestra di ricezione nel wirehark poiché è composta dalla dimensione della finestra e dal fattore di ridimensionamento della finestra all'interno dell'intestazione TCP. Entrambe le parti della connessione TCP pubblicizzeranno la loro finestra di ricezione, ma generalmente quella a cui tieni è quella che riceve la maggior parte dei dati. Nel tuo caso, è il "server" poiché il client si sta caricando sul server
  • La finestra di congestione. Questo è il controllo del flusso imposto dal mittente. Questo è gestito dal sistema operativo e non viene visualizzato nell'intestazione TCP. Controlla la velocità di invio rapido dei dati.

Nel file di acquisizione che hai fornito. Possiamo vedere che il buffer di ricezione non è mai pieno:

inserisci qui la descrizione dell'immagine

La mia analisi è che il mittente non sta inviando abbastanza velocemente perché la finestra di invio (ovvero la finestra di controllo della congestione) non si sta aprendo abbastanza per soddisfare l'RWIN del destinatario. Quindi in breve il destinatario dice "Dammi di più" e quando Windows è il mittente non invia abbastanza velocemente.

Ciò è dimostrato dal fatto che nel grafico sopra RWIN rimane aperto e con un tempo di andata e ritorno di 0,09 secondi e un RWIN di ~ 500.000 byte possiamo aspettarci un throughput massimo in base al prodotto ritardo della larghezza di banda (500000 /0.09) * 8 = ~ 42 Mbit / s (e stai ottenendo circa ~ 5 nella tua vincita alla cattura Linux).

Come sistemarlo?

Non lo so. interface tcp set global congestionprovider=ctcpsembra la cosa giusta da fare per me perché aumenterebbe la finestra di invio (che è un altro termine per la finestra di congestione). Hai detto che non funziona. Quindi, solo per assicurarsi:

  1. Hai riavviato dopo averlo abilitato?
  2. Chimney è scarico? Se è forse prova a disattivarlo come esperimento. Non so cosa viene scaricato esattamente quando abilitato, ma se il controllo della finestra di invio è uno di questi, forse il congestionprovider non ha alcun effetto quando questo è abilitato ... Sto solo supponendo ...
  3. Inoltre, penso che questo potrebbe essere pre Windows 7, ma potresti provare ad aggiungere e giocare con le due chiavi di registro denominate DefaultSendWindow e DefaultReceiveWindow in HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameters. Se anche questi funzionano, probabilmente ti sei accorto che è stato disattivato.
  4. Ancora un'altra ipotesi, prova a dare un'occhiata netsh interface tcp show heuristics. Penso che potrebbe essere RWIN, ma non lo dice, quindi magari gioca con la disabilitazione / abilitazione nel caso in cui abbia un impatto sulla finestra di invio.
  5. Inoltre, assicurati che i tuoi driver siano aggiornati sul tuo client di test. Forse qualcosa è appena rotto.

Vorrei provare tutti questi esperimenti con tutte le funzionalità di scaricamento per iniziare per eliminare la possibilità che i driver di rete stiano eseguendo una riscrittura / modifica delle cose (tenere d'occhio la CPU mentre lo scarico è disattivato). La struttura TCP_OFFLOAD_STATE_DELEGATED sembra implicare almeno che l' offload di CWnd sia almeno possibile.


2
Ho segnalato la tua "risposta" perché la tua non è una risposta; Ho subito ricevuto il voto negativo; ora vedo come "persone" stia votando la tua "non risposta" ... davvero divertente
Pat

1
@Pat: puoi anche fare clic sul numero di voto per visualizzare la suddivisione di Voti positivi / negativi. Attualmente non hai voti negativi sulla tua risposta. La mia risposta non risolve il suo problema (ma nessuna risposta lo fa ancora), spiega e localizza il problema (si spera correttamente!) Che è un passo importante nella risoluzione dei problemi.
Kyle Brandt,

@ Kyle Brandt se accetti la tua non è una risposta mi chiedo perché non venga "automaticamente" rimosso senza ulteriori considerazioni ?? e ti sbagli; Ho ricevuto un voto negativo (non votato) "appena" quando ho segnalato la tua "risposta"; quello non è stato ancora rimosso. Sembra che tu suoni secondo regole "speciali" qui.
Pat

1
@Pat Se aiuta, la non risposta di Kyle è stata incredibilmente utile. Ora ho un'idea più chiara di quali buffer sono limitati e di conseguenza mi sento un po 'più vicino a una soluzione adeguata. A volte domande come questa possono essere uno sforzo collaborativo che, con un po 'di editing giudizioso, può diventare una Q corretta e una A corretta .
SmallClanger,

@SmallClanger con tutto il rispetto, SF ha una serie di regole che dovrebbero essere seguite da tutti i suoi utenti incluso Kyle Brandt; se la sua non è una risposta, deve essere cancellata o spostata come commento, indipendentemente dal numero di amici che ha nel club dei "moderatori".
Pat

5

Ci sono state alcune informazioni fantastiche qui da @Pat e @Kyle. Sicuramente presta attenzione alla spiegazione di @ Kyle del TCP ricevere e inviare finestre, penso che ci sia stata una certa confusione in questo. Per confondere ulteriormente le cose, iperf usa il termine "finestra TCP" con l' -wimpostazione che è una specie di termine ambiguo per quanto riguarda la finestra scorrevole di ricezione, invio o complessiva. Ciò che effettivamente fa è impostare il buffer di invio socket per l' -cistanza (client) e il buffer di ricezione socket sull'istanza -s(server). 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 ));
}

Come menziona Kyle, il problema non riguarda la finestra di ricezione nella finestra di Linux, ma il mittente non sta aprendo abbastanza la finestra di invio. Non è che non si apra abbastanza velocemente, si limita a 64k.

La dimensione predefinita del buffer socket su Windows 7 è 64k. Ecco cosa dice la documentazione sulla dimensione del buffer socket in relazione alla velocità effettiva su MSDN

Quando si inviano dati su una connessione TCP utilizzando i socket di Windows, è importante mantenere una quantità sufficiente di dati in sospeso (inviati ma non ancora riconosciuti) in TCP al fine di ottenere il massimo rendimento. Il valore ideale per la quantità di dati in sospeso per ottenere la migliore velocità effettiva per la connessione TCP è chiamato dimensione ISB (send back ideale). Il valore ISB è una funzione del prodotto di ritardo della larghezza di banda della connessione TCP e della finestra di ricezione pubblicizzata dal ricevitore (e in parte la quantità di congestione nella rete).

Ok, blah blah blah, ora eccoci:

Le applicazioni che eseguono una richiesta di invio bloccante o non bloccante alla volta in genere si affidano al buffering di invio interno di Winsock per ottenere un throughput decente. Il limite del buffer di invio per una determinata connessione è controllato dall'opzione socket SO_SNDBUF. Per il metodo di invio bloccante e non bloccante, il limite del buffer di invio determina la quantità di dati mantenuti in sospeso in TCP . Se il valore ISB per la connessione è superiore al limite del buffer di invio, la velocità effettiva raggiunta sulla connessione non sarà ottimale.

Il throughput medio del tuo ultimo test iperf utilizzando la finestra 64k è di 5,8 Mbps. Viene da Statistiche> Riepilogo in Wireshark, che conta tutti i bit. Probabilmente, iperf sta contando il throughput di dati TCP pari a 5,7 Mbps. Vediamo le stesse prestazioni anche con il test FTP, ~ 5,6 Mbps.

Il throughput teorico con un buffer di invio 64k e RTT 91ms è .... 5,5 Mbps. Abbastanza vicino per me.

Se esaminiamo il test iperf della finestra da 1 MB, il tput è 88,2 Mbps (86,2 Mbps per i soli dati TCP). Il tput teorico con una finestra da 1 MB è di 87,9 Mbps. Ancora una volta, abbastanza vicino per il lavoro del governo.

Ciò dimostra che il buffer del socket di invio controlla direttamente la finestra di invio e che, insieme alla finestra di ricezione dall'altro lato, controlla la velocità effettiva. La finestra di ricezione pubblicizzata ha spazio, quindi non siamo limitati dal ricevitore.

Aspetta, che mi dici di questa attività di autotuning? Windows 7 non gestisce queste cose automaticamente? Come accennato, Windows gestisce il ridimensionamento automatico della finestra di ricezione, ma può anche gestire in modo dinamico anche il buffer di invio. Torniamo alla pagina MSDN:

Buffering di invio dinamico per TCP è stato aggiunto su Windows 7 e Windows Server 2008 R2. Per impostazione predefinita, il buffering di invio dinamico per TCP è abilitato a meno che un'applicazione non imposti l'opzione socket SO_SNDBUF sul socket stream.

iperf utilizza SO_SNDBUFquando si utilizza l' -wopzione, quindi il buffering di invio dinamico sarebbe disabilitato. Tuttavia, se non lo usi -w, non lo usa SO_SNDBUF. Il buffering di invio dinamico dovrebbe essere attivo per impostazione predefinita, ma è possibile verificare:

netsh winsock show autotuning

La documentazione dice che puoi disabilitarlo con:

netsh winsock set autotuning off

Ma non ha funzionato per me. Ho dovuto apportare una modifica al registro e impostarlo su 0:

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

Non penso che disabilitare questo aiuterà; è solo una FYI.

Perché il buffer di invio non viene ridimensionato al di sopra del 64k predefinito quando si inviano dati a un box Linux con molto spazio nella finestra di ricezione? Ottima domanda I kernel Linux hanno anche uno stack TCP di autotuning. Come T-Pain e Kanye che fanno un duetto autotune insieme, potrebbe non suonare bene. Forse c'è qualche problema con quei due stack TCP di autotuning che parlano tra loro.

Un'altra persona ha avuto un problema come il tuo ed è stata in grado di risolverlo con una modifica del registro per aumentare la dimensione del buffer di invio predefinita. Sfortunatamente, questo non sembra più funzionare, almeno non per me quando l'ho provato.

A questo punto, penso sia chiaro che il fattore limitante è la dimensione del buffer di invio sull'host Windows. Dato che non sembra crescere correttamente in modo dinamico, cosa deve fare una ragazza?

Puoi:

  • Utilizzare le applicazioni che consentono di impostare il buffer di invio, ad esempio l'opzione della finestra
  • Utilizzare un proxy Linux locale
  • Utilizzare un proxy Windows remoto?
  • Apri un caso con Microsofhahahahahahaha
  • birra

Disclaimer: ho trascorso molte ore a ricercare questo ed è corretto per quanto ne so e google-fu. Ma non giurerei sulla tomba di mia madre (è ancora viva).


Input fantasici; grazie. Sto usando iperf 2.0.4, sperimenterò le impostazioni e aggiornerò anche il mio OP con alcuni nuovi limiti.
SmallClanger,

Ok, ho aggiornato la mia "risposta" sulla base di ulteriori ricerche e dei tuoi recenti test
karyhead il

Grazie. Almeno in parte è bello sapere che non sto solo impazzendo. Ho letto alcuni blog / thread dei giorni XP / 2003 che raccomandano quelle impostazioni del registro, ma sono stati scritti prima di Vista / 2008 e sono abbastanza sicuro che vengano ignorati in Vista in poi. Penso che in realtà aumenterò un biglietto con MS su questo (
augurami buona

1
Uno strumento utile che ho trovato nella mia ricerca era tcpanalyzer.exe nell'SDK ( microsoft.com/en-us/download/details.aspx?id=8279 ). È un netstat grafico che è possibile selezionare una singola connessione e ottenere le statistiche TCP come RTT, cwnd, ritrasmissioni, ecc. Potrei far aprire il cwnd ben oltre la dimensione del buffer di invio, ma il tput non è aumentato e il wirehark verificato che è ancora inviare buffer limitato.
Karyhead,

1
Ho trovato commenti su diversi forum sui comandi "netsh" che non funzionano come pubblicizzato in 7/8 e che le persone sono state costrette ad inserire manualmente le voci di registro corrispondenti; Mi chiedo se qualcosa del genere potrebbe accadere con l'opzione CTCP.
Pat

4

Dopo aver ottimizzato lo stack TCP, è possibile che si verifichi un collo di bottiglia nel livello Winsock. Ho scoperto che la configurazione di Winsock (driver di funzione ausiliaria nel registro) fa una grande differenza per la velocità di upload (invio di dati al server) in Windows 7. Microsoft ha riconosciuto un bug nell'autotuning TCP per socket non bloccanti - solo il tipo di socket utilizzato dai browser ;-)

Aggiungi la chiave DWORD per DefaultSendWindow e impostala su BDP o superiore. Sto usando 256000.

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

La modifica dell'impostazione di Winsock per i download potrebbe essere utile: aggiungere una chiave per DefaultReceiveWindow.

Puoi sperimentare varie impostazioni a livello di socket utilizzando il proxy Fiddler e i comandi per regolare le dimensioni del buffer del socket client e server:

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

Ulteriori informazioni aggiuntive. Hai un link di riferimento per il bug MS, per caso?
SmallClanger

3

Dopo aver letto tutte le analisi nelle risposte, questo problema sembra davvero che tu stia eseguendo Windows7 / 2008R2 aka Windows 6.1

Lo stack di rete (TCP / IP e Winsock) in Windows 6.1 era orribilmente imperfetto e presentava tutta una serie di bug e problemi di prestazioni che Microsoft alla fine ha risolto in molti anni di hotfix dalla versione iniziale di 6.1.

Il modo migliore per applicare questi aggiornamenti rapidi è setacciare manualmente tutte le pagine pertinenti su support.microsoft.com e richiedere e scaricare manualmente le versioni LDR degli aggiornamenti rapidi dello stack di rete (ce ne sono molte dozzine).

Per trovare gli aggiornamenti rapidi pertinenti, è necessario utilizzare www.bing.com con la seguente query di ricerca site:support.microsoft.com 6.1.7601 tcpip.sys

È inoltre necessario comprendere come funzionano i treni di aggiornamento rapido LDR / GDR in Windows 6.1

In genere utilizzavo il mio elenco di correzioni LDR (non solo le correzioni dello stack di rete) per Windows 6.1 e quindi applicavo queste correzioni in modo proattivo a qualsiasi server / client Windows 6.1 che ho riscontrato. È stato un compito molto dispendioso verificare periodicamente la presenza di nuovi aggiornamenti rapidi LDR.

Fortunatamente, Microsoft ha interrotto la pratica degli hotfix LDR con le versioni più recenti del sistema operativo e le correzioni dei bug sono ora disponibili tramite i servizi di aggiornamento automatico di Microsoft.

AGGIORNAMENTO : solo un esempio di molti bug di rete in Windows7SP1 - https://support.microsoft.com/en-us/kb/2675785

AGGIORNAMENTO 2 : Ecco un altro aggiornamento rapido che aggiunge un interruttore netsh per forzare il ridimensionamento della finestra dopo la seconda ritrasmissione di un pacchetto SYN (per impostazione predefinita, il ridimensionamento della finestra è disabilitato dopo la ritrasmissione di 2 pacchetti SYN) https://support.microsoft.com/en- noi / kb / 2780879


Grazie Christoph; alcuni nuovi input molto interessanti su questo e che la 'caratteristica' di ritrasmissione di SYN è molto strana; Non riesco a vedere l'obiettivo del design dietro a quello. (Forse una sorta di rilevamento della congestione del greggio?). Tutti i test originali sono stati eseguiti su Win7SP1; presto proveremo Win10 e spetta a me riproporre gran parte di questo per vedere come funziona.
SmallClanger

Con quale ramo di Windows 10 testerai? Non ho ancora alcuna esperienza con lo stack di rete in Windows 10.
Christoph Wegener,

L'Enterprise 1511 è ciò a cui stiamo puntando.
SmallClanger,

Vedo. È abbastanza difficile decidere su un ramo con Windows 10 poiché ce ne sono così tanti. Ho già riscontrato un problema con Windows 10 in cui non potevo usare una particolare funzione perché ero su un ramo LTSB. Vorrei che Microsoft avesse ridotto il numero di filiali disponibili in generale e invece avesse migliorato la loro documentazione su quali correzioni e funzionalità sono incluse in ogni build ....
Christoph Wegener

1

Vedo che questo è un post un po 'più vecchio, ma potrebbe aiutare gli altri.

In breve, devi abilitare "Ottimizzazione automatica della finestra di ricezione":

netsh int tcp set global autotuninglevel=normal

CTCP non significa nulla senza abilitato sopra.

Se disattivi "Ricevi ottimizzazione automatica della finestra" rimarrai bloccato con una dimensione del pacchetto di 64 KB che ha un impatto negativo sui RTT lunghi nelle connessioni a banda larga elevate. Puoi anche provare le opzioni "limitato" e "fortemente limitato".

Ottimo riferimento: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html


1

Stavo riscontrando un problema simile con i client Windows (Windows 7). Ho affrontato la maggior parte del debug che hai attraversato, disabilitando l'algoritmo Nagle, TCP Chimney Offloading e tonnellate di altre modifiche alle impostazioni relative a TCP. Nessuno di loro ha avuto alcun effetto.

Ciò che alla fine l'ho risolto per me è stato modificare la finestra di invio predefinita nel registro del servizio AFD. Il problema sembra essere correlato al file afd.sys. Ho testato diversi client, alcuni hanno mostrato il caricamento lento, altri no, ma tutti erano macchine Windows 7. Le macchine che presentavano il comportamento lento avevano la stessa versione AFD.sys. La soluzione alternativa del registro è necessaria per i computer con determinate versioni di AFD.sys (scusate, non ricordate i numeri di versione).

HKLM \ CurrentControlSet \ Services \ AFD \ Parameters

Aggiungi - DWORD - DefaultSendWindow

Valore - Decimale - 1640960

Quel valore è qualcosa che ho trovato qui: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Penso di usare il valore corretto, dovresti calcolarlo tu stesso usando:

per esempio. Upload pubblicizzato: 15 Mbps = 15.000 Kbps

(15000/8) * 1024 = 1920000

Da quanto ho capito, il software client dovrebbe generalmente ignorare questa impostazione nel registro, ma in caso contrario, viene utilizzato il valore predefinito e apparentemente il valore predefinito è molto basso in alcune versioni del file AFD.sys.

Ho notato che la maggior parte dei prodotti MS presentava il problema del caricamento lento (IE, Mini-redirector (WebDAV), FTP tramite Windows Explorer, ecc ...) Quando si utilizzavano software di terze parti (es. Filezilla) non avevo gli stessi rallentamenti .

AFD.sys ha effetto su tutte le connessioni Winsock, quindi questa correzione dovrebbe applicarsi a FTP, HTTP, HTTPS, ecc ...

Inoltre, questa correzione è stata elencata sopra anche da qualche parte, quindi non voglio prendermi il merito se funziona per nessuno, tuttavia c'erano così tante informazioni in questo thread che temevo che potesse essere stato corretto.


0

Bene, mi sono imbattuto in una situazione simile (la mia domanda qui ) e alla fine ho dovuto disabilitare l'euristica del ridimensionamento TCP, impostare manualmente il profilo di autotuning e abilitare 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. 

0

Non ho abbastanza punti per commentare, quindi posterò una "risposta". Sto riscontrando quello che sembra essere un problema simile / identico (vedi la domanda serverfault qui ). Il mio (e probabilmente il tuo) problema è il buffer di invio del client iperf su Windows. Non cresce oltre i 64 KB. Windows dovrebbe aumentare dinamicamente il buffer quando non viene esplicitamente dimensionato dal processo. Ma quella crescita dinamica non sta avvenendo.

Non sono sicuro del tuo grafico di ridimensionamento della finestra che mostra l'apertura della finestra fino a 500.000 byte per il tuo caso "lento" di Windows. Mi aspettavo di vedere quel grafico aperto solo a ~ 64.000 byte dato che sei limitato a 5 Mbps.


0

Questo è un thread affascinante e corrisponde esattamente ai problemi che ho avuto usando Win7 / iperf per testare la produttività su tubi lunghi e grassi.

La soluzione per Windows 7 è eseguire il comando seguente sia sul server iperf che sul client.

netsh interface tcp set global autotuninglevel = sperimentale

NB: prima di eseguire questa operazione, assicurarsi di registrare lo stato corrente dell'autotuning:

interfaccia netsh tcp mostra globale

Livello di sintonizzazione automatica della finestra di ricezione: disabilitato

Quindi eseguire il server / client iperf su ciascuna estremità della pipe.

Reimpostare il valore di autotuning dopo i test:

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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.