Entre os servidores, windows-in-Finland <-> linux-in-Germany
estou enfrentando um upload 100x mais lento que o download ( windows -> linux
é 100x mais lento que windows <- linux
).
Detalhes e pesquisas existentes
Inicialmente, observei esse problema com clientes Windows em todo o mundo e percebi que também posso reproduzi-lo em ambientes de data center controlados.
Para reproduzir o problema, estou usando o provedor de datacenter Hetzner, com a Windows
máquina na Finlândia (servidor dedicado, Windows Server 2019), fazendo upload para ambos:
- Linux Hetzner dedicado Alemanha: lento
- Linux Hetzner Cloud VM Alemanha: rápido
Ambos estão no mesmo parque de datacenter e, portanto, ambos têm 37 ms
ping
da máquina Windows. Enquanto a conexão entre a Finlândia e a Alemanha geralmente está na rede privada da Hetzner, ela está atualmente sendo redirecionada por meio de rotas públicas de Internet devido à interrupção do cabo submarino C-LION1 2024 do Mar Báltico ( mensagem de status da Hetzner sobre isso ), então a conexão "simula" o uso de rotas e peerings normais de Internet pública.
Estou medindo com iperf3
, windows <- linux
:
C:\Users\Administrator\Downloads\iperf3.17.1_64\iperf3.17.1_64>iperf3.exe -c linux-germany-dedicated.examle.com
Connecting to host linux-germany-dedicated.examle.com, port 5201
[ 5] local 192.0.2.1 port 62234 connected to 192.0.2.2 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 15.8 MBytes 132 Mbits/sec
[ 5] 1.00-2.00 sec 1.88 MBytes 15.7 Mbits/sec
[ 5] 2.00-3.00 sec 1.38 MBytes 11.5 Mbits/sec
[ 5] 3.00-4.00 sec 1.75 MBytes 14.7 Mbits/sec
[ 5] 4.00-5.00 sec 2.25 MBytes 18.9 Mbits/sec
[ 5] 5.00-6.00 sec 2.88 MBytes 24.1 Mbits/sec
[ 5] 6.00-7.00 sec 3.25 MBytes 27.3 Mbits/sec
[ 5] 7.00-8.00 sec 3.38 MBytes 28.3 Mbits/sec
[ 5] 8.00-9.00 sec 2.75 MBytes 23.1 Mbits/sec
[ 5] 9.00-10.00 sec 1.25 MBytes 10.5 Mbits/sec
Mais iperf3
observações:
- A outra direção (adicionando
-R
)iperf3
é muito mais rápida, a ~900 Mbit/s. (Observe que os lados do Linux estão usando o controle de congestionamento BBR, o que provavelmente ajuda nessa direção.) - Ao fazer download com 30 conexões (
iperf3
com-P 30
), a conexão de 1 Gbit/s é atingida no máximo, sugerindo que o problema é a taxa de transferência de upload de uma única conexão de upload TCP . - Ao substituir a máquina Windows por uma Linux na Finlândia, ambas as direções atingem o máximo de 1 Gbit/s de conexão. Isso me leva a concluir que o envolvimento do Windows é a falha .
- Observe que há um artigo da Microsoft alegando que
iperf3
é o melhor para medições de alto desempenho no Windows. Isso não é relevante para esta questão porque se aplica apenas a conexões >= ~10 Gbit/s, e o fato de que iperf3 em várias máquinas Windows/Linux no mesmo datacenter prova que a velocidade de 1 Gbit/s é facilmente atingíveliperf3
em ambas as direções.
Em 2021, o Dropbox lançou um artigo Aumentando a velocidade de upload do Dropbox e melhorando a pilha TCP do Windows , que aponta o tratamento incorreto (incompleto) do Windows de retransmissões TCP; a Microsoft publicou Melhorias algorítmicas aumentam o desempenho do TCP na Internet junto com isso.
Isso parece explicar em grande parte, e o Wireguard lento, mas apenas para upload do Windows, mostra uma solução potencial, ou seja, alterar o número de filas RSS ( Receive Side Scaling ) para 1:
ethtool -L eth0 combined 1
Isso muda de 16
(16 threads no meu servidor Linux dedicado) para 1 e aumenta a velocidade de upload do iperf3 convergente de 10.5
para 330
Mbit/s .
Isso é bom, mas deveria ser 1000 Mbit/s.
Especialmente estranho: Ao testar windows -> linux-Hetzner-Cloud
em vez de windows -> Hetzner-dedicated
, observo velocidades de upload perfeitas:
C:\Users\Administrator\Downloads\iperf3.17.1_64\iperf3.17.1_64>iperf3.exe -c linux-germany-hcloud.example.com
Connecting to host linux-germany-hcloud.example.com, port 5201
[ 5] local 192.0.2.1 port 55615 connected to 192.0.2.3 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 108 MBytes 903 Mbits/sec
[ 5] 1.00-2.00 sec 112 MBytes 942 Mbits/sec
...
[ 5] 9.00-10.00 sec 112 MBytes 942 Mbits/sec
Isso é estranho, porque a máquina de nuvem tem especificações muito mais baixas. Ela tem 8 núcleos virtuais, mas sua ethtool -l
saída já é padrão Combined: 1
porque, sendo uma VM, ela não suporta RSS de forma alguma:
root@linux-germany-hcloud ~ # ethtool -x enp1s0
RX flow hash indirection table for enp1s0 with 1 RX ring(s):
Operation not supported
RSS hash key:
Operation not supported
RSS hash function:
toeplitz: on
xor: off
crc32: off
Então, de alguma forma, a máquina mais fraca não tem o problema. Talvez haja alguma coisa inteligente de hardware NIC acontecendo na máquina dedicada que cria o problema? O que poderia ser?
Eu já tentei desabilitar o TCP Segment Offloading ( ethtool -K eth0 tso off
), mas isso não afeta os resultados. O recurso que causou o problema no artigo do Dropbox ( flow-director-atr
) não está disponível na minha NIC, então não pode ser isso.
Pergunta
O que pode explicar o gargalo adicional de 3x no upload entre os dois servidores Linux?
Como posso obter uploads rápidos apenas do Windows?
Mais informações sobre o meio ambiente
- Ambas as máquinas Linux usam a mesma versão Linux
6.6.33 x86_64
e os mesmossysctl
s (garantidos via NixOS), que são:net.core.default_qdisc=fq net.core.rmem_max=1073741824 net.core.wmem_max=1073741824 net.ipv4.conf.all.forwarding=0 net.ipv4.conf.net0.proxy_arp=0 net.ipv4.ping_group_range=0 2147483647 net.ipv4.tcp_congestion_control=bbr net.ipv4.tcp_rmem=4096 87380 1073741824 net.ipv4.tcp_wmem=4096 87380 1073741824
- Servidor Windows 2019
Version 1809 (OS Build 17763.6293)
Editar 1
Descobri que consigo upload de 950 Mbit/s do Windows para outras máquinas dedicadas da Hetzner. As máquinas dedicadas para as quais o upload é lento têm em comum o fato de terem placas de rede Intel de 10 Gbit/s; de lspci
:
01:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
lsmod | grep ixgbe
sugere que o ixgbe
driver seja usado aqui.
ixgbe
também é mencionado no artigo do Dropbox acima . O artigo "Por que o Flow Director causa reordenação de pacotes?" que eles vinculam menciona Intel 82599
especificamente. Também encontrei este tópico e1000-devel onde alguém menciona o problema em 2011, mas nenhuma solução é apresentada.
Ao usar o cartão de 1 Gbit Intel Corporation I210 Gigabit Network Connection (rev 03)
presente no mesmo modelo de servidor, o problema desaparece e obtenho 950 Mbit/s.
Então parece haver algo específico sobre 82599ES
/ ixgbe
que causa o problema.
Edição 2: Intel Flow Director
e tentar fora da árvoreixgbe
Uma pesquisa no Google intel disable flowdirector
produz https://access.redhat.com/solutions/528603 mencionando Intel 82599.
Ajuda:
O Intel Flow Director é um recurso de driver e NIC da Intel que fornece direção inteligente e programável de tráfego de rede semelhante (ou seja, um "fluxo") para filas de recebimento específicas.
Por padrão, o Flow Director opera no modo ATR (Application Targeted Receive). Isso executa hash regular no estilo RSS quando tráfego não visto anteriormente é recebido. No entanto, quando o tráfego é transmitido, a tupla (ou "fluxo") desse tráfego é inserida na tabela de hash de recebimento. O tráfego futuro recebido na mesma tupla será recebido no núcleo que o transmitiu. O processo de envio e recebimento pode então ser fixado no mesmo núcleo que a fila de recebimento para melhor afinidade de cache da CPU.
Observe que a pesquisa da comunidade mostrou que o ATR pode causar tráfego TCP Out-of-Order quando processos são migrados entre CPUs . É melhor fixar explicitamente processos em CPUs ao usar o modo ATR.
O FlowDirector é mencionado no artigo do Dropbox, assim como o ATR
.
A "pesquisa comunitária" mencionada é o mesmo artigo "Por que o Flow Director causa reordenação de pacotes?" ao qual o Dropbox se refere.
Fazendo o sugerido
ethtool -K net0 ntuple on
melhora a velocidade de 20 Mbit/s para 130 Mbit/s (com o padrão ethtool -L net0 combined 16
). Executá-lo por mais tempo ( iperf3 --time 30
) faz com que ele caia para 80 Mbit/s após 16 segundos. Usar ntuple on
junto com combined 16
não melhora mais.
Portanto, esta não é uma solução completa.
Testando a options ixgbe FdirMode=0
abordagem em seguida.
Sobre ram256g-1
:
rmmod ixgbe; modprobe ixgbe FdirMode=0; sleep 2; ifconfig net0 94.130.221.7/26 ; ip route add 192.0.2.2 dev net0 proto static scope link ; ip route add default via 192.0.2.2 dev net0 proto static ; echo done
dmesg
mostra
ixgbe: unknown parameter 'FdirMode' ignored
Isso apesar de https://www.kernel.org/doc/Documentation/networking/ixgbe.txt documentá-lo:
FdirMode
--------
Valid Range: 0-2 (0=off, 1=ATR, 2=Perfect filter mode)
Default Value: 1
Flow Director filtering modes.
Então 0=off
parece ainda mais desejável que os outros dois, que supostamente são os que ntuple
on/off
alternam entre eles.
https://access.redhat.com/solutions/330503 diz
A Intel optou por expor algumas configurações como um parâmetro de módulo em seu driver SourceForge, no entanto, o kernel Linux upstream tem uma política de não expor um recurso como uma opção de módulo quando ele pode ser configurado de maneiras já disponíveis, então você só verá alguns parâmetros de módulo em drivers Intel fora da árvore do kernel Linux upstream.
A Red Hat segue os métodos do kernel upstream, então essas opções não estarão na versão RHEL do driver, mas a mesma coisa pode ser feita com
ethtool
(e sem) uma recarga de módulo.
Isso sugere que isso 0=off
não é realmente possível.
Ou talvez funcione com modprobe.d
opções, mas não com o modprobe
comando?
Código relevante:
- Kernel antigo com a
FdirMode
opção: - Novo kernel sem:
- https://github.com/torvalds/linux/blob/b86545e02e8c22fb89218f29d381fa8e8b91d815/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c#L648
- Sugere que o Flow Director só seja habilitado se o comprimento da fila RSS for
> 1
- Então provavelmente definir o comprimento da fila como 1 com
ethtool -L
(que é--set-channels
) já deve resolver isso.
- Sugere que o Flow Director só seja habilitado se o comprimento da fila RSS for
- https://github.com/torvalds/linux/blob/b86545e02e8c22fb89218f29d381fa8e8b91d815/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c#L648
Mas parece que https://github.com/intel/ethernet-linux-ixgbe ainda está sendo desenvolvido ativamente e suporta todas as opções antigas. Também suporta FdirPballoc
o que nunca existiu em torvalds/linux
. Isso é descrito em: https://forum.proxmox.com/threads/pve-kernel-4-10-17-1-wrong-ixgbe-driver.35868/#post-175787
Também relacionado: https://www.phoronix.com/news/Intel-IGB-IXGBE-Firmware-Update
Talvez eu deva tentar construir e carregar isso?
Desse driver, FDirMode
também foi removido:
- https://github.com/intel/ethernet-linux-ixgbe/commit/a9a37a529704c584838169b4cc1f877a38442d36
- https://github.com/intel/ethernet-linux-ixgbe/commit/a72af2b2247c8f6bb599d30e1763ff88a1a0a57a
De https://lists.osuosl.org/pipermail/intel-wired-lan/Week-of-Mon-20160919/006629.html :
ethtool -K ethX ntuple on
Isso habilitará o modo "filtro perfeito", mas ainda não há filtros, então os pacotes recebidos retornarão ao RSS.
Testado
ethtool -K net0 ntuple on
ethtool --config-ntuple net0 flow-type tcp4 src-ip 192.0.2.1 action 1
Não melhorou a velocidade.
Também descobri que a velocidade no Linux 6.3.1
parece ser de 90 Mbit/s, enquanto no 6.11.3
.
Compilando o out-of-tree ethernet-linux-ixgbe
no Hetzner Rescue System Linux (old)
que tem 6.3.1
(ainda não há lançamento para Linux 6.11
):
wget https://github.com/intel/ethernet-linux-ixgbe/releases/download/v5.21.5/ixgbe-5.21.5.tar.gz
tar xaf *.tar.gz
cd ixgbe-*/src && make -j
# because disconnecting the ethernet below will hang all commands
# from the Rescue Mode's NFS mount if not already loaded into RAM
ethtool --help
timeout 1 iperf3 -s
dmesg | grep -i fdir
modinfo /root/ixgbe-*/src/ixgbe.ko # shows all desired options
rmmod ixgbe; insmod /root/ixgbe-*/src/ixgbe.ko; sleep 2; ifconfig eth1 94.130.221.7/26 ; ip route add 192.0.2.2 dev eth1 scope link ; ip route add default via 192.0.2.2 dev eth1 ; echo done
iperf3 -s
Este driver fornece 450 Mbit/s mais sólidos imediatamente.
rmmod ixgbe; insmod /root/ixgbe-*/src/ixgbe.ko FdirPballoc=3; sleep 2; ifconfig eth1 94.130.221.7/26 ; ip route add 192.0.2.2 dev eth1 scope link ; ip route add default via 192.0.2.2 dev eth1 ; echo done
dmesg | grep -i fdir
iperf3 -s
Não traz nenhuma melhoria.
Experimente também:
AtrSampleRate
Um valor de 0 indica que o ATR deve ser desabilitado e nenhuma amostra será coletada.
rmmod ixgbe; insmod /root/ixgbe-*/src/ixgbe.ko AtrSampleRate=0; sleep 2; ifconfig eth1 94.130.221.7/26 ; ip route add 192.0.2.2 dev eth1 scope link ; ip route add default via 192.0.2.2 dev eth1 ; echo done
dmesg | grep -i atrsample
iperf3 -s
Não traz nenhuma melhoria.
ethtool -L net0 combined 1
aqui também não traz nenhuma melhoria, e
ethtool -K eth1 ntuple on
ethtool -L eth1 combined 12 # needed, otherwise the out-of-tree ixgbe driver complains with `rmgr: Cannot insert RX class rule: Invalid argument` when `combined 1` is set
ethtool --config-ntuple eth1 flow-type tcp4 src-ip 192.0.2.1 action 1
também não traz nenhuma melhoria.
Edição 3: NIC alterado
Alterei a NIC do servidor Linux de Intel 82599ES para Intel X710, que usa o i40e
driver Linux.
O problema persistiu.
Suspeito que seja porque o X710 também suporta o Intel Flow Director.
A mitigação parcial ethtool -L eth0 combined 1
tem o mesmo efeito que para o 82599ES.
O comando
ethtool --set-priv-flags eth0 flow-director-atr off
(o que é possível i40e
, mas não ixgbe
) mencionado pelo Dropbox como solução alternativa só alcançou a mesma aceleração que ethtool -L eth0 combined 1
(em torno de 400 Mbit/s).
Curiosamente, Hetzner relatou que as máquinas Hetzner Cloud também são equipadas com Intel X710 , mas não apresentam o problema.