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.
netsh int tcp set global timestamps=enabled