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 -s
em 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)iperf -c -w1M
Windows SYN - Windows 64kb, Escala 1 - Linux SYN, ACK: Janela 14kb, Escala: 9
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 | nc
redirecionamento para /dev/null
o servidor para descartar iperf
e 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:
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 -w1m
em 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.5
no servidor e ntttcp -s -m 1,0,1.2.3.5 -t 10
no 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
iperf
s, 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
ntttcp
rastreamento 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/urandom
um host linux quase idêntico (1.2.3.6) usando o Cygwinncftp
. Novamente, o limite está lá. O padrão é o mesmo no Windows Filezilla.
Alterar o iperf
comprimento 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.
fonte
netsh int tcp set global timestamps=enabled
Respostas:
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
Editar 30/06/2014
para ver se o CTCP está realmente "ligado"
ie
CTCP aumenta agressivamente a janela de envio
http://technet.microsoft.com/en-us/library/bb878127.aspx
fonte
Set-NetTCPSetting
com o-CongestionProvider
parâ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.aspxiperf
e a Janela ainda nunca ultrapassou ~ 520kb. Outra coisa está limitando o CWND antes que esse algoritmo agressivo possa mostrar quaisquer benefícios.Esclarecendo o problema:
O TCP possui duas janelas:
No arquivo de captura que você forneceu. Podemos ver que o buffer de recebimento nunca está excedendo:
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=ctcp
parece 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: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.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.
fonte
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
-w
configuraçã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-c
instância (cliente) e o buffer de recebimento do soquete na-s
instância (servidor). Emsrc/tcp_window_size.c
: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
Ok, blá blá blá, agora vamos lá:
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 iperf usa
SO_SNDBUF
ao usar a-w
opçã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:A documentação diz que você pode desativá-lo com:
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:
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).
fonte
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.
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:
fonte
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
fonte
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":
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
fonte
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.
fonte
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:
fonte
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.
fonte
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 =
fonte