A versão TL; DR
Assista a este elenco ASCII ou a este vídeo - depois, encontre as razões pelas quais isso está acontecendo. A descrição de texto a seguir fornece mais contexto.
Detalhes da configuração
- A Machine 1 é um laptop Arch Linux, no qual
ssh
é gerado, conectando-se a um SBC com Armbian (Orange PI Zero). - O próprio SBC é conectado via Ethernet a um roteador DSL e possui um IP 192.168.1.150
- O laptop está conectado ao roteador via WiFi - usando um dongle oficial Raspberry PI WiFi.
- Há também outro laptop (Máquina 2) conectado via Ethernet ao roteador DSL.
Comparando o link com o iperf3
Quando comparado iperf3
, o vínculo entre o laptop e o SBC é inferior aos 56 MBits / s teóricos - como esperado, pois essa é uma conexão Wi-Fi em um edifício de apartamentos de 2,4 GHz muito lotado .
Mais especificamente: após a execução iperf3 -s
no SBC, os seguintes comandos são executados no laptop:
# iperf3 -c 192.168.1.150
Connecting to host 192.168.1.150, port 5201
[ 5] local 192.168.1.89 port 57954 connected to 192.168.1.150 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 2.99 MBytes 25.1 Mbits/sec 0 112 KBytes
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 28.0 MBytes 23.5 Mbits/sec 5 sender
[ 5] 0.00-10.00 sec 27.8 MBytes 23.4 Mbits/sec receiver
iperf Done.
# iperf3 -c 192.168.1.150 -R
Connecting to host 192.168.1.150, port 5201
Reverse mode, remote host 192.168.1.150 is sending
[ 5] local 192.168.1.89 port 57960 connected to 192.168.1.150 port 5201
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 3.43 MBytes 28.7 Mbits/sec
...
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 39.2 MBytes 32.9 Mbits/sec 375 sender
[ 5] 0.00-10.00 sec 37.7 MBytes 31.6 Mbits/sec receiver
Então, basicamente, o upload para o SBC atinge cerca de 24 MBits / s, e o download a partir dele ( -R
) atinge 32 MBits / s.
Benchmarking com SSH
Dado isso, vamos ver como o SSH se sai. Eu experimentei os problemas que levaram a este post ao usar rsync
e borgbackup
- ambos usando SSH como uma camada de transporte ... Então, vamos ver como o SSH funciona no mesmo link:
# cat /dev/urandom | \
pv -ptebar | \
ssh root@192.168.1.150 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]
Bem, essa é uma velocidade abismal! Muito mais lento que a velocidade esperada do link ...
(Caso você não esteja ciente pv -ptevar
: ele exibe a taxa atual e média de dados passando por ele. Nesse caso, vemos que a leitura /dev/urandom
e o envio de dados via SSH para o SBC está atingindo, em média, 400 KB / s - ou seja, 3,2 MBits / s, um número bem menor que os 24 MBits / s esperados.)
Por que nosso link está funcionando com 13% de sua capacidade?
Talvez seja /dev/urandom
culpa nossa ?
# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]
Não, definitivamente não.
Talvez seja o próprio SBC? Talvez seja muito lento para processar? Vamos tentar executar o mesmo comando SSH (ou seja, enviar dados para o SBC), mas desta vez a partir de outra máquina (Máquina 2) conectada pela Ethernet:
# cat /dev/urandom | \
pv -ptebar | \
ssh root@192.168.1.150 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s]
Não, isso funciona bem - o daemon SSH no SBC pode (facilmente) manipular os 11 MBytes / s (ou seja, os 100 MBits / s) fornecidos pelo link Ethernet.
E a CPU do SBC é carregada ao fazer isso?
Não.
Então...
- Em termos de rede (conforme
iperf3
), devemos ser capazes de fazer 10x a velocidade - nossa CPU pode acomodar facilmente a carga
- ... e não envolvemos nenhum outro tipo de E / S (por exemplo, unidades).
O que diabos está acontecendo?
Netcat e ProxyCommand para o resgate
Vamos tentar netcat
conexões simples e antigas - elas funcionam tão rápido quanto o esperado?
No SBC:
# nc -l -p 9988 | pv -ptebar > /dev/null
No laptop:
# cat /dev/urandom | pv -ptebar | nc 192.168.1.150 9988
117MiB 0:00:33 [3.82MiB/s] [3.57MiB/s]
Funciona! E roda na velocidade esperada - muito melhor, 10x melhor -.
Então, o que acontece se eu executar o SSH usando um ProxyCommand para usar nc?
# cat /dev/urandom | \
pv -ptebar | \
ssh -o "Proxycommand nc %h %p" root@192.168.1.150 'cat >/dev/null'
101MiB 0:00:30 [3.38MiB/s] [3.33MiB/s]
Trabalho! 10x velocidade.
Agora estou um pouco confuso - ao usar um "nu" nc
como um Proxycommand
, você não está basicamente fazendo exatamente a mesma coisa que o SSH? ou seja, criando um soquete, conectando-se à porta 22 da SBC e depois colocando o protocolo SSH sobre ela?
Por que existe essa enorme diferença na velocidade resultante?
PS: Este não foi um exercício acadêmico - meu borg
backup é executado 10 vezes mais rápido por causa disso. Só não sei por que :-)
EDIT : Adicionado um "vídeo" do processo aqui . Contando os pacotes enviados a partir da saída do ifconfig, é claro que em ambos os testes estamos enviando 40 MB de dados, transmitindo-os em aproximadamente 30K pacotes - apenas muito mais devagar quando não estiver em uso ProxyCommand
.
nc
usa buffer de linha, enquantossh
que não tem buffer. Portanto (ou se houver), o tráfego ssh envolve mais pacotes.