Windows TCP Window Scaling Atingir o platô muito cedo

50

Cenário: Temos vários clientes Windows que fazem upload regularmente de arquivos grandes (FTP / SVN / HTTP PUT / SCP) para servidores Linux a uma distância de ~ 100-160ms. Temos uma largura de banda síncrona de 1 Gbit / s no escritório e os servidores são instâncias da AWS ou hospedados fisicamente nos DCs dos EUA.

O relatório inicial era que os uploads para uma nova instância do servidor eram muito mais lentos do que podiam ser. Isso ocorreu nos testes e em vários locais; os clientes estavam vendo estáveis ​​2-5Mbit / s para o host em seus sistemas Windows.

Entrei iperf -sem uma instância da AWS e depois em um cliente Windows no escritório:

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

O último número pode variar significativamente em testes subseqüentes (Caprichos da AWS), mas geralmente está entre 70 e 130Mbit / s, o que é mais do que suficiente para nossas necessidades. Ao compartilhar a sessão, posso ver:

  • iperf -c Windows SYN - Janela 64kb, Escala 1 - Linux SYN, ACK: Janela 14kb, Escala: 9 (* 512) redimensionamento da janela do iperf com janela padrão de 64kb
  • iperf -c -w1M Windows SYN - Windows 64kb, Escala 1 - Linux SYN, ACK: Janela 14kb, Escala: 9 redimensionamento da janela do iperf com janela padrão de 1 MB

Claramente, o link pode sustentar esse alto rendimento, mas preciso explicitamente definir o tamanho da janela para usá-lo, o que a maioria dos aplicativos do mundo real não me permite. Os handshakes TCP usam os mesmos pontos de partida em cada caso, mas o forçado é escalado

Por outro lado, de um cliente Linux na mesma rede, um straight iperf -c(usando o sistema padrão de 85kb) me fornece:

[  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

Sem forçar, ele aumenta conforme o esperado. Isso não pode ser algo nos saltos intermediários ou em nossos switches / roteadores locais e parece afetar os clientes do Windows 7 e 8. Eu li muitos guias sobre o ajuste automático, mas normalmente são sobre como desativar o dimensionamento para solucionar um terrível kit de rede doméstica ruim.

Alguém pode me dizer o que está acontecendo aqui e me dar uma maneira de corrigi-lo? (De preferência, algo que eu possa aderir ao registro via GPO.)

Notas

A instância do AWS Linux em questão tem as seguintes configurações de kernel aplicadas em 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

Usei o dd if=/dev/zero | ncredirecionamento para /dev/nullo servidor para descartar iperfe remover outros gargalos possíveis, mas os resultados são os mesmos. Os testes com ncftp(Cygwin, Windows nativo, Linux) são dimensionados da mesma maneira que os testes iperf acima em suas respectivas plataformas.

Editar

Eu vi outra coisa consistente aqui que pode ser relevante: insira a descrição da imagem aqui

Este é o primeiro segundo da captura de 1 MB, ampliada. Você pode ver o Início lento em ação enquanto a janela aumenta e o buffer fica maior. Existe um pequeno platô de ~ 0,2s exatamente no ponto em que o teste padrão do iperf da janela fica nulo para sempre. É claro que esse é escalado para alturas muito mais vertiginosas, mas é curioso que exista uma pausa no dimensionamento (os valores são 1022 bytes * 512 = 523264) antes disso.

Atualização - 30 de junho.

Acompanhamento das várias respostas:

  • Ativando o CTCP - Isso não faz diferença; a escala da janela é idêntica. (Se bem entendi, essa configuração aumenta a taxa na qual a janela de congestionamento é ampliada, em vez do tamanho máximo que ela pode atingir)
  • Ativando carimbos de data / hora TCP. - Nenhuma mudança aqui também.
  • Algoritmo de Nagle - Isso faz sentido e, pelo menos, significa que eu provavelmente posso ignorar esses blips específicos no gráfico como qualquer indicação do problema.
  • Arquivos pcap: arquivo zip disponível aqui: https://www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip (anonimato com bittwiste, extrai para ~ 150MB, pois um de cada cliente do SO para comparação)

Atualização 2 - 30 de junho

O, então, seguindo a sugestão de Kyle, habilitei o ctcp e desabilitei o descarregamento de chaminés: 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

Mas, infelizmente, nenhuma alteração na taxa de transferência.

Tenho uma pergunta de causa / efeito aqui: Os gráficos são do valor RWIN definido nas ACKs do servidor para o cliente. Com os clientes Windows, estou certo ao pensar que o Linux não está escalando esse valor além desse ponto baixo porque o CWIN limitado do cliente impede que mesmo esse buffer seja preenchido? Poderia haver outra razão para o Linux limitar artificialmente o RWIN?

Nota: Tentei ativar o ECN para o inferno; mas nenhuma mudança, aí.

Atualização 3 - 31 de junho.

Nenhuma alteração após heurística desabilitada e ajuste automático de RWIN. Atualizei os drivers de rede Intel para o mais recente (12.10.28.0) com software que expõe ajustes de funcionalidade por meio das guias do gerenciador de dispositivos. A placa é uma placa de rede de 82579V integrada (eu vou fazer mais alguns testes de clientes com a realtek ou outros fornecedores)

Focando a NIC por um momento, tentei o seguinte (principalmente descartando culpados improváveis):

  • Aumente os buffers de recebimento para 2k de 256 e transmita buffers para 2k de 512 (ambos agora no máximo) - sem alterações
  • Desativado todo o descarregamento da soma de verificação IP / TCP / UDP. - nenhuma mudança.
  • Desativado grande envio Offload - Nada.
  • Desativado IPv6, agendamento de QoS - Nowt.

Atualização 3 - 3 de julho

Tentando eliminar o lado do servidor Linux, iniciei uma instância do Server 2012R2 e repeti os testes usando iperf(binário cygwin) e NTttcp .

Com iperf, eu tive que especificar explicitamente -w1mem ambos os lados antes que a conexão aumentasse para ~ 5Mbit / s. (Aliás, eu poderia ser verificado e o BDP de ~ 5Mbits na latência de 91ms é quase precisamente 64kb. Descubra o limite ...)

Os binários ntttcp mostraram agora essa limitação. Usando ntttcpr -m 1,0,1.2.3.5no servidor e ntttcp -s -m 1,0,1.2.3.5 -t 10no cliente, posso ver uma taxa de transferência muito melhor:

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 coloca nos níveis que eu estava obtendo com janelas explicitamente grandes iperf. Estranhamente, no entanto, 80 MB em 1273 buffers = um buffer de 64 kB novamente. Um outro wireshark mostra um RWIN bom e variável voltando do servidor (fator de escala 256) que o cliente parece cumprir; talvez o ntttcp esteja relatando incorretamente a janela de envio.

Atualização 4 - 3 de julho

A pedido de @ karyhead, fiz mais alguns testes e gerou mais algumas capturas, aqui: https://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • Mais dois iperfs, ambos do Windows para o mesmo servidor Linux de antes (1.2.3.4): um com tamanho de soquete de 128k e janela padrão de 64k (restringe a ~ 5Mbit / s novamente) e outro com janela de envio de 1MB e soquete de 8kb padrão Tamanho. (escalas mais altas)
  • Um ntttcprastreamento do mesmo cliente Windows para uma instância do Server 2012R2 EC2 (1.2.3.5). aqui, a taxa de transferência varia bem. Nota: O NTttcp faz algo estranho na porta 6001 antes de abrir a conexão de teste. Não tenho certeza do que está acontecendo lá.
  • Um rastreamento de dados de FTP, carregando 20 MB de /dev/urandomum host linux quase idêntico (1.2.3.6) usando o Cygwin ncftp. Novamente, o limite está lá. O padrão é o mesmo no Windows Filezilla.

Alterar o iperfcomprimento do buffer faz a diferença esperada para o gráfico da sequência de tempo (seções muito mais verticais), mas a taxa de transferência real é inalterada.

SmallClanger
fonte
11
Um exemplo raro de um problema bem pesquisado que não está obviamente na documentação. Bom - vamos torcer para que alguém encontre uma solução (porque, de alguma forma, acho que também posso usá-la).
TomTom
2
Tente ativar os carimbos de data / hora do RFC 1323, pois eles são desativados por padrão no Windows, enquanto o Linux os habilita por padrão). netsh int tcp set global timestamps=enabled
Brian
3
O atraso de 200 ms é provavelmente o algoritmo Nagle em ação. Como os dados são recebidos pelo TCP em uma conexão específica, ele envia uma confirmação somente se uma das seguintes condições for verdadeira: Nenhuma confirmação foi enviada para o segmento anterior recebido; Um segmento é recebido, mas nenhum outro segmento chega dentro de 200 milissegundos para essa conexão.
precisa
2
Alguma chance de colocar algumas capturas de pacotes de um dos remetentes mais lentos em algum lugar?
Kyle Brandt
Atualizei meu OP com os resultados desses testes e links para arquivos de captura representativos.
SmallClanger

Respostas:

15

Você já tentou ativar o TCP composto (CTCP) em seus clientes Windows 7/8.

Por favor leia:

Aumentando o desempenho do lado do remetente para transmissão com alto BDP

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

...

Esses algoritmos funcionam bem para BDPs pequenos e tamanhos menores de janelas de recebimento. No entanto, quando você tem uma conexão TCP com um tamanho de janela de recebimento grande e um BDP grande , como replicar dados entre dois servidores localizados em um link de WAN de alta velocidade com um tempo de ida e volta de 100 ms , esses algoritmos não aumentam a janela de envio rápido o suficiente para utilizar totalmente a largura de banda da conexão .

Para utilizar melhor a largura de banda das conexões TCP nessas situações, a pilha TCP / IP da próxima geração inclui o TCP composto (CTCP). O CTCP aumenta mais agressivamente a janela de envio para conexões com grandes tamanhos de janela de recebimento e BDPs . O CTCP tenta maximizar a taxa de transferência nesses tipos de conexões, monitorando as variações e perdas de atraso. Além disso, o CTCP garante que seu comportamento não afete negativamente outras conexões TCP.

...

O CTCP é ativado por padrão em computadores executando o Windows Server 2008 e desativado por padrão em computadores que executam o Windows Vista. Você pode ativar o CTCP com o netsh interface tcp set global congestionprovider=ctcpcomando Você pode desativar o CTCP com o netsh interface tcp set global congestionprovider=nonecomando

Editar 30/06/2014

para ver se o CTCP está realmente "ligado"

> netsh int tcp show global

ie

insira a descrição da imagem aqui

PO disse:

Se eu entendi isso corretamente, essa configuração aumenta a taxa na qual a janela de congestionamento é ampliada, em vez do tamanho máximo que ela pode atingir

CTCP aumenta agressivamente a janela de envio

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

TCP composto

Os algoritmos existentes que impedem que um ponto TCP de envio sobrecarregue a rede são conhecidos como início lento e prevenção de congestionamentos. Esses algoritmos aumentam a quantidade de segmentos que o remetente pode enviar, conhecido como janela de envio, ao enviar inicialmente dados na conexão e ao recuperar de um segmento perdido. O início lento aumenta a janela de envio em um segmento TCP completo para cada segmento de confirmação recebido (para TCP no Windows XP e Windows Server 2003) ou para cada segmento reconhecido (para TCP no Windows Vista e Windows Server 2008). A prevenção de congestionamentos aumenta a janela de envio em um segmento TCP completo para cada janela completa de dados que é reconhecida.

Esses algoritmos funcionam bem para velocidades de mídia da LAN e tamanhos menores de janelas TCP. No entanto, quando você possui uma conexão TCP com um tamanho de janela de recebimento grande e um grande atraso de largura de banda (alta largura de banda e alto atraso), como replicar dados entre dois servidores localizados em um link de WAN de alta velocidade com uma viagem de ida e volta de 100 ms Com o tempo, esses algoritmos não aumentam a janela de envio com rapidez suficiente para utilizar totalmente a largura de banda da conexão. Por exemplo, em um link WAN de 1 Gigabit por segundo (Gbps) com um tempo de viagem de ida e volta de 100 ms (RTT), pode levar até uma hora para a janela de envio aumentar inicialmente para o tamanho de janela grande anunciado pelo receptor e recuperar quando houver segmentos perdidos.

Para utilizar melhor a largura de banda das conexões TCP nessas situações, a pilha TCP / IP da próxima geração inclui o TCP composto (CTCP). O CTCP aumenta de forma mais agressiva a janela de envio para conexões com grandes tamanhos de janelas de recebimento e grandes produtos de atraso de largura de banda. O CTCP tenta maximizar a taxa de transferência nesses tipos de conexões, monitorando as variações e perdas de atraso . O CTCP também garante que seu comportamento não afeta negativamente outras conexões TCP.

Nos testes realizados internamente na Microsoft, o tempo de backup de arquivos grandes foi reduzido pela metade para uma conexão de 1 Gbps com um RTT de 50 ms. As conexões com um produto de atraso de largura de banda maior podem ter um desempenho ainda melhor. O CTCP e o Autoajuste da janela de recebimento trabalham juntos para aumentar a utilização do link e podem resultar em ganhos substanciais de desempenho para conexões de produtos com grande atraso na largura de banda.

Pat
fonte
3
Apenas como complemento para esta resposta, o equivalente do PowerShell no Server 2012 / Win8.1 está Set-NetTCPSettingcom o -CongestionProviderparâmetro ... que aceita CCTP, DCTCP e Padrão. Os clientes e servidores Windows usam diferentes provedores de congestionamento padrão. technet.microsoft.com/en-us/library/hh826132.aspx
Ryan Ries
Entendo o que você está dizendo, mas parece que não se aplica. Para o efeito, corri 30 minutos iperfe a Janela ainda nunca ultrapassou ~ 520kb. Outra coisa está limitando o CWND antes que esse algoritmo agressivo possa mostrar quaisquer benefícios.
SmallClanger
há um bug antigo (já corrigido) do Vista que apresentava esse tipo de problema ao transmitir protocolos não HTML. Seu problema parece exatamente o mesmo ao transferir o mesmo arquivo por HTML ou, digamos, por FTP?
Pat
@ Pat - Sim. As confirmações SVN (via HTTP e HTTPS) e as transferências FTP para outro sistema na AWS também exibem os mesmos limites.
SmallClanger
e quanto ao firewall do cliente Win? você pode testar com o firewall completamente desligado? veja aqui: ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
Pat
12

Esclarecendo o problema:

O TCP possui duas janelas:

  • A janela de recebimento: Quantos bytes restam no buffer. Este é o controle de fluxo imposto pelo receptor. Você pode ver o tamanho da janela de recebimento no wireshark, pois ela é composta pelo tamanho da janela e pelo fator de escala da janela dentro do cabeçalho TCP. Os dois lados da conexão TCP anunciarão a janela de recebimento, mas geralmente o que mais lhe interessa é o recebimento da maior parte dos dados. No seu caso, é o "servidor", pois o cliente está fazendo o upload para o servidor
  • A janela de congestionamento. Esse é o controle de fluxo imposto pelo remetente. Isso é mantido pelo sistema operacional e não aparece no cabeçalho TCP. Ele controla a taxa com que velocidade os dados serão enviados.

No arquivo de captura que você forneceu. Podemos ver que o buffer de recebimento nunca está excedendo:

insira a descrição da imagem aqui

Minha análise é que o remetente não está enviando rápido o suficiente porque a janela de envio (também conhecida como janela de controle de congestionamento) não está abrindo o suficiente para satisfazer o RWIN do receptor. Em resumo, o receptor diz "Dê-me mais" e, quando o Windows é o remetente, não está enviando rápido o suficiente.

Isso é evidenciado pelo fato de que no gráfico acima o RWIN permanece aberto e, com o tempo de ida e volta de 0,09 segundos e um RWIN de ~ 500.000 bytes, podemos esperar uma taxa de transferência máxima de acordo com o produto de atraso de largura de banda (500000 /0,09) * 8 = ~ 42 Mbit / s (e você está obtendo apenas ~ 5 na sua vitória na captura do Linux).

Como corrigi-lo?

Eu não sei. interface tcp set global congestionprovider=ctcpparece a coisa certa a fazer, porque aumentaria a janela de envio (que é outro termo para a janela de congestionamento). Você disse que não está funcionando. Então, apenas para ter certeza:

  1. Você reiniciou depois de ativar isso?
  2. A descarga da chaminé está ligada? Se for o caso, tente desativá-lo como um experimento. Eu não sei o que exatamente é descarregado quando isso está ativado, mas se o controle da janela de envio é um deles, talvez o provedor de congestionamento não tenha efeito quando isso estiver ativado ... Estou apenas supondo ...
  3. Além disso, acho que isso pode ser anterior ao Windows 7, mas você pode tentar adicionar e jogar com as duas chaves de registro chamadas DefaultSendWindow e DefaultReceiveWindow em HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameters. Se isso funcionar, você provavelmente já está com o ctcp desativado.
  4. Ainda outro palpite, tente conferir netsh interface tcp show heuristics. Eu acho que pode ser RWIN, mas não diz, então talvez brinque com desabilitar / habilitar isso, caso isso afete a janela de envio.
  5. Além disso, verifique se os drivers estão atualizados no seu cliente de teste. Talvez algo esteja quebrado.

Eu tentaria todas essas experiências com todos os recursos de descarregamento para começar, a fim de eliminar a possibilidade de que os drivers de rede estejam reescrevendo / modificando as coisas (fique de olho na CPU enquanto a descarga estiver desativada). A estrutura TCP_OFFLOAD_STATE_DELEGATED parece implicar pelo menos que o descarregamento de CWnd é pelo menos possível.

Kyle Brandt
fonte
2
Eu relatei sua "resposta" porque a sua não é uma resposta; Eu imediatamente fui derrotado; agora eu vejo como "povo" é up-voto o seu "não-resposta" ... muito engraçado
Pat
11
@ Pat: Você pode clicar no número do voto também para ver a distribuição de Upvotes / Downvotes. Atualmente, você não tem votos negativos na sua resposta. Minha resposta não resolve o problema dele (mas nenhuma resposta ainda), explica e localiza o problema (espero que seja correto!), Que é uma etapa importante na solução de problemas.
Kyle Brandt
@ Kyle Brandt, se você aceitar o seu, não é uma resposta. Gostaria de saber por que ele não é "automaticamente" removido sem nenhuma consideração adicional? e você está errado; Recebi um voto negativo (não votado) "assim que" relatei sua "resposta"; esse ainda não foi removido. Parece que você joga de acordo com regras "especiais" aqui.
Pat
11
@ Pat Se ajudar, a não resposta de Kyle foi incrivelmente útil. Agora tenho uma ideia mais clara de quais buffers estão sendo limitados e, como resultado, sinto que estou um pouco mais perto de uma solução adequada. Às vezes, perguntas como essa podem ser um esforço colaborativo que, com um pouco de edição criteriosa, pode se tornar um Q e um A adequados .
SmallClanger
@SmallClanger com todo o respeito, SF tem um conjunto de regras que devem ser seguidas por todos os seus usuários, incluindo Kyle Brandt; se a resposta dele não for uma resposta, ela deve ser apagada ou movida como comentário, independentemente de quantos amigos ele tenha entre o clube "moderadores".
Pat
5

Houve ótimas informações aqui por @Pat e @Kyle. Definitivamente, preste atenção à explicação de @ Kyle sobre o TCP receber e enviar janelas, acho que houve alguma confusão em torno disso. Para confundir ainda mais, o iperf usa o termo "janela TCP" com a -wconfiguração que é um termo ambíguo em relação à janela deslizante de recebimento, envio ou em geral. O que ele realmente faz é definir o buffer de envio do soquete para a -cinstância (cliente) e o buffer de recebimento do soquete na -sinstância (servidor). Em 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 ));
}

Como Kyle menciona, o problema não está na janela de recebimento na caixa do Linux, mas o remetente não está abrindo a janela de envio o suficiente. Não é que ele não abra rápido o suficiente, apenas limita a 64k.

O tamanho padrão do buffer de soquete no Windows 7 é 64k. Aqui está o que a documentação diz sobre o tamanho do buffer de soquete em relação à taxa de transferência no MSDN

Ao enviar dados por uma conexão TCP usando soquetes do Windows, é importante manter uma quantidade suficiente de dados pendentes (enviados mas ainda não reconhecidos) no TCP para obter a maior taxa de transferência. O valor ideal para a quantidade de dados pendentes para obter a melhor taxa de transferência para a conexão TCP é chamado de tamanho ideal de envio de backlog (ISB). O valor ISB é uma função do produto de atraso de largura de banda da conexão TCP e da janela de recebimento anunciada do receptor (e parcialmente a quantidade de congestionamento na rede).

Ok, blá blá blá, agora vamos lá:

Os aplicativos que executam uma solicitação de envio de bloqueio ou não de bloqueio por vez geralmente dependem do buffer de envio interno do Winsock para obter um rendimento decente. O limite do buffer de envio para uma determinada conexão é controlado pela opção de soquete SO_SNDBUF. Para o método de envio de bloqueio e sem bloqueio, o limite do buffer de envio determina a quantidade de dados mantidos pendentes no TCP . Se o valor ISB da conexão for maior que o limite do buffer de envio, a taxa de transferência alcançada na conexão não será ótima.

A taxa de transferência média do seu teste iperf mais recente usando a janela de 64k é de 5,8 Mbps. Isso é de Estatísticas> Resumo no Wireshark, que conta todos os bits. Provavelmente, o iperf está contando a taxa de transferência de dados TCP, que é de 5,7 Mbps. Também vemos o mesmo desempenho com o teste FTP, ~ 5.6Mbps.

O rendimento teórico com um buffer de envio de 64k e RTT de 91ms é .... 5.5Mbps. Perto o suficiente para mim.

Se observarmos o teste iperf da janela de 1 MB, a taxa é de 88,2 Mbps (86,2 Mbps apenas para dados TCP). A carga teórica com uma janela de 1 MB é de 87,9 Mbps. Novamente, perto o suficiente para o trabalho do governo.

O que isso demonstra é que o buffer do soquete de envio controla diretamente a janela de envio e que, juntamente com a janela de recebimento do outro lado, controla a taxa de transferência. A janela de recebimento anunciada tem espaço; portanto, não estamos limitados pelo destinatário.

Espere, e esse negócio de ajuste automático? O Windows 7 não lida com essas coisas automaticamente? Como foi mencionado, o Windows lida com o dimensionamento automático da janela de recebimento, mas também pode lidar dinamicamente com o buffer de envio. Vamos voltar à página do MSDN:

O buffer de envio dinâmico para TCP foi adicionado no Windows 7 e Windows Server 2008 R2. Por padrão, o buffer de envio dinâmico para TCP está ativado, a menos que um aplicativo defina a opção de soquete SO_SNDBUF no soquete de fluxo.

O iperf usa SO_SNDBUFao usar a -wopção, portanto o buffer de envio dinâmico seria desativado. No entanto, se você não usar -w, ele não usará SO_SNDBUF. O buffer de envio dinâmico deve estar ativado por padrão, mas você pode verificar:

netsh winsock show autotuning

A documentação diz que você pode desativá-lo com:

netsh winsock set autotuning off

Mas isso não funcionou para mim. Eu tive que fazer uma alteração no registro e definir como 0:

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

Eu não acho que desabilitar isso vai ajudar; é apenas um FYI.

Por que o buffer de envio não está acima dos 64k padrão ao enviar dados para uma caixa Linux com bastante espaço na janela de recebimento? Ótima pergunta. Os kernels do Linux também têm uma pilha TCP de ajuste automático. Como T-Pain e Kanye fazendo um dueto de autotune juntos, isso pode não parecer bom. Talvez haja algum problema com as duas pilhas TCP de ajuste automático conversando entre si.

Outra pessoa teve um problema como o seu e conseguiu corrigi-lo com uma edição do Registro para aumentar o tamanho padrão do buffer de envio. Infelizmente, isso não parece funcionar mais, pelo menos não funcionou quando tentei.

Neste ponto, acho claro que o fator limitante é o tamanho do buffer de envio no host do Windows. Dado que não parece crescer dinamicamente adequadamente, o que uma garota deve fazer?

Você pode:

  • Use aplicativos que permitem definir a opção de envio de buffer, ou seja, janela
  • Use um proxy Linux local
  • Usar um proxy remoto do Windows?
  • Abra um caso com Microsofhahahahahahaha
  • Cerveja

Isenção de responsabilidade: Passei muitas horas pesquisando isso e é correto o melhor que sei e o google-fu. Mas eu não juro pelo túmulo de minha mãe (ela ainda está viva).

karyhead
fonte
Entrada fantástica; obrigado. Estou usando o iperf 2.0.4, vou experimentar as configurações e atualizar meu OP com alguns novos limites também.
SmallClanger
Ok, eu atualizei meu "resposta" com base em mais pesquisas e os testes recentes
karyhead
Obrigado. Pelo menos em parte é bom saber que não estou ficando louco. Eu li alguns blogs / tópicos dos dias XP / 2003 que recomendam essas configurações de registro, mas eles foram escritos antes do Vista / 2008 e tenho certeza de que eles são ignorados no Vista em diante. Eu acho que realmente vai levantar um bilhete com MS sobre isso (me desejem sorte)
SmallClanger
11
Uma ferramenta útil que encontrei na minha pesquisa foi o tcpanalyzer.exe no SDK ( microsoft.com/en-us/download/details.aspx?id=8279 ). É um netstat gráfico que você pode selecionar uma conexão individual e obter estatísticas de TCP como RTT, cwnd, retransmissões etc. Eu poderia fazer com que o cwnd se abrisse muito além do tamanho do buffer de envio, mas a tput não aumentou e o wireshark foi verificado que ainda é enviar buffer limitado.
precisa saber é
11
Eu encontrei comentários em vários fóruns sobre comandos "netsh" que não funcionam como anunciados em 7/8, e pessoas sendo forçadas a inserir manualmente as entradas de registro correspondentes; Gostaria de saber se algo assim pode estar acontecendo com a opção CTCP.
Pat
4

Depois de ajustar a pilha TCP, você ainda poderá ter um gargalo na camada Winsock. Descobri que a configuração do Winsock (Driver de Função Auxiliar no Registro) faz uma enorme diferença nas velocidades de upload (envio de dados para o servidor) no Windows 7. A Microsoft reconheceu um bug no auto-ajuste do TCP para soquetes sem bloqueio - apenas o tipo de soquete que os navegadores usam ;-)

Adicione a chave DWORD para DefaultSendWindow e defina-a como BDP ou superior. Estou usando 256000.

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

Alterar a configuração do Winsock para downloads pode ajudar - adicione uma chave para DefaultReceiveWindow.

Você pode experimentar várias configurações de nível de soquete usando o Proxy Fiddler e os comandos para ajustar os tamanhos de buffer do soquete do cliente e do servidor:

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
fonte
Excelente informação adicional. Você tem um link de referência para o bug do MS, por acaso?
SmallClanger
3

Depois de ler todas as análises nas respostas, esse problema parece muito com o Windows7 / 2008R2, também conhecido como Windows 6.1

A pilha de rede (TCP / IP e Winsock) no Windows 6.1 era terrivelmente falha e apresentava uma série de bugs e problemas de desempenho que a Microsoft finalmente resolveu ao longo de muitos anos de hotfix desde o lançamento inicial do 6.1.

A melhor maneira de aplicar esses hotfixes é peneirar manualmente todas as páginas relevantes em support.microsoft.com e solicitar e baixar manualmente as versões LDR dos hotfixes de pilha de rede (existem muitas dezenas).

Para encontrar os hotfixes relevantes, você deve usar www.bing.com com a seguinte consulta de pesquisa site:support.microsoft.com 6.1.7601 tcpip.sys

Você também precisa entender como os trens de hotfix LDR / GDR funcionam no Windows 6.1

Geralmente, eu costumava manter minha própria lista de correções de LDR (não apenas correções de pilha de rede) para o Windows 6.1 e, em seguida, aplicava essas correções proativamente a qualquer servidor / cliente do Windows 6.1 que encontrei. Foi uma tarefa muito demorada verificar regularmente novos hotfixes LDR.

Felizmente, a Microsoft interrompeu a prática dos hotfixes LDR com versões mais recentes do sistema operacional e as correções estão agora disponíveis através dos serviços de atualização automática da Microsoft.

ATUALIZAÇÃO : Apenas um exemplo de muitos erros de rede no Windows7SP1 - https://support.microsoft.com/en-us/kb/2675785

ATUALIZAÇÃO 2 : Aqui está outro hotfix que adiciona uma opção netsh para forçar o dimensionamento da janela após a segunda retransmissão de um pacote SYN (por padrão, o dimensionamento da janela é desativado após a retransmissão de 2 pacotes SYN) https://support.microsoft.com/en- eua / kb / 2780879

Christoph Wegener
fonte
Obrigado Christoph; alguma entrada nova e muito interessante sobre isso e que o 'recurso' de retransmissão SYN é muito estranho; Não consigo ver o objetivo do design por trás disso. (Algum tipo de detecção de congestionamento bruto, talvez?). Todos os testes originais foram feitos no Win7SP1; testaremos o Win10 em breve e cabe a mim repetir muito disso para ver como ele se sai.
SmallClanger
Com qual ramo do Windows 10 você testará? Ainda não tenho nenhuma experiência com a pilha de rede no Windows 10.
Christoph Wegener
A empresa 1511 é o nosso objetivo.
SmallClanger
Eu vejo. É muito difícil decidir sobre uma ramificação no Windows 10, pois existem muitas. Já encontrei um problema no Windows 10 em que não podia usar um recurso específico porque estava em uma filial do LTSB. Desejo Microsoft tinha reduzido o número de agências disponíveis em geral e, em vez melhorado a sua documentação sobre o que correções e recursos estão incluídos em cada build ....
Christoph Wegener
1

Vejo que esse post é um pouco mais antigo, mas poderia ajudar outras pessoas.

Em resumo, você deve habilitar o "Ajuste automático da janela de recebimento":

netsh int tcp set global autotuninglevel=normal

CTCP não significa nada sem o ativado acima.

Se você desabilitar o "Ajuste automático da janela de recebimento", ficará preso no tamanho do pacote de 64 KB, o que afeta negativamente os RTT longos nas conexões de banda larga alta. Você também pode experimentar as opções "restrito" e "altamente restrito".

Muito boa referência: https://www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html

spricer
fonte
1

Eu estava enfrentando um problema semelhante com os clientes Windows (Windows 7). Eu passei pela maioria das depurações que você passou, desativando o algoritmo Nagle, o TCP Chimney Offloading e muitas outras alterações de configuração relacionadas ao TCP. Nenhum deles teve qualquer efeito.

O que finalmente o corrigiu foi a modificação da janela de envio padrão no registro do serviço AFD. O problema parece estar relacionado ao arquivo afd.sys. Testei vários clientes, alguns exibiram o upload lento e outros não, mas todos eram máquinas Windows 7. Máquinas que exibiram o comportamento lento tinham a mesma versão AFD.sys. A solução alternativa do registro é necessária para computadores com determinadas versões do AFD.sys (desculpe, não lembre as versões #).

HKLM \ CurrentControlSet \ Services \ AFD \ Parameters

Adicionar - DWORD - DefaultSendWindow

Valor - decimal - 1640960

Esse valor é algo que encontrei aqui: https://helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

Eu acho que para usar o valor adequado, você deve calculá-lo usando:

por exemplo. Upload anunciado: 15 Mbps = 15.000 Kbps

(15000/8) * 1024 = 1920000

Pelo que entendi, o software cliente geralmente deve substituir essa configuração no registro, mas, se não, o valor padrão é usado e, aparentemente, o valor padrão é muito baixo em algumas versões do arquivo AFD.sys.

Percebi que a maioria dos produtos MS apresentava o problema de carregamento lento (IE, minirr redirecionador (WebDAV), FTP através do Windows Explorer, etc.). .

O AFD.sys afeta todas as conexões Winsock, portanto, essa correção deve se aplicar ao FTP, HTTP, HTTPS, etc ...

Além disso, essa correção também foi listada acima em algum lugar, por isso não quero receber crédito por isso, se funcionar para alguém, no entanto, havia tantas informações nesse segmento que eu temia que pudesse ter sido encoberto.

jjspierx
fonte
0

Bem, eu mesmo enfrentei uma situação semelhante (minha pergunta aqui ) e, no final, tive que desativar as heurísticas de escala TCP, definir manualmente o perfil de ajuste automático e ativar o 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
fonte
0

Como não tenho pontos suficientes para comentar, postarei uma "resposta". Estou tendo o que parece ser um problema semelhante / idêntico (consulte a pergunta sobre falha do servidor aqui ). Meu (e provavelmente o seu) problema é o buffer de envio do cliente iperf no Windows. Não cresce além de 64 KB. O Windows deve aumentar dinamicamente o buffer quando não for explicitamente dimensionado pelo processo. Mas esse crescimento dinâmico não está acontecendo.

Não tenho certeza sobre o gráfico de escala de janela que mostra a janela abrindo até 500.000 bytes para o seu caso "lento" do Windows. Eu esperava ver esse gráfico aberto para apenas ~ 64.000 bytes, uma vez que você está limitado a 5 Mbps.

Chris Stankevitz
fonte
0

Este é um tópico fascinante e corresponde exatamente aos problemas que tive ao usar o Win7 / iperf para testar a taxa de transferência em cachimbos longos.

A solução para o Windows 7 é executar o seguinte comando no servidor iperf E no cliente.

netsh interface tcp set global autotuninglevel = experimental

NB: Antes de fazer isso, certifique-se de registrar o status atual do ajuste automático:

netsh interface tcp show global

Nível de ajuste automático da janela de recebimento: desativado

Em seguida, execute o servidor / cliente iperf em cada extremidade do pipe.

Redefina o valor do ajuste automático após seus testes:

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
fonte