La version TL; DR
Regardez cette distribution ASCII ou cette vidéo - puis trouvez les raisons pour lesquelles cela se produit. La description textuelle qui suit fournit plus de contexte.
Détails de l'installation
- La machine 1 est un ordinateur portable Arch Linux, sur lequel
ssh
est généré, se connectant à un SBC fonctionnant sous Armbian (un Orange PI Zero). - Le SBC lui-même est connecté via Ethernet à un routeur DSL et a une IP de 192.168.1.150
- L'ordinateur portable est connecté au routeur via WiFi - à l'aide d'un dongle WiFi Raspberry PI officiel.
- Il y a aussi un autre ordinateur portable (Machine 2) connecté via Ethernet au routeur DSL.
Analyse comparative du lien avec iperf3
Lorsque comparé avec iperf3
, le lien entre l'ordinateur portable et le SBC est inférieur aux 56 Mbits / s théoriques - comme prévu, car il s'agit d'une connexion WiFi dans un 2,4 GHz très fréquenté (immeuble à appartements) .
Plus précisément: après exécution iperf3 -s
sur le SBC, les commandes suivantes sont exécutées sur l'ordinateur portable:
# 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
Donc, fondamentalement, le téléchargement vers le SBC atteint environ 24 Mo / s, et le téléchargement depuis ( -R
) atteint 32 Mo / s.
Analyse comparative avec SSH
Cela étant, voyons comment s'en sort SSH. J'ai d'abord rencontré les problèmes qui ont conduit à ce message lors de l'utilisation rsync
et borgbackup
- les deux utilisant SSH comme couche de transport ... Voyons donc comment SSH fonctionne sur le même lien:
# cat /dev/urandom | \
pv -ptebar | \
ssh root@192.168.1.150 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]
Eh bien, c'est une vitesse abyssale! Beaucoup plus lent que la vitesse de liaison attendue ...
(Dans le cas où vous n'êtes pas au courant pv -ptevar
: il affiche le débit actuel et moyen des données qui le traversent. Dans ce cas, nous voyons que la lecture /dev/urandom
et l'envoi des données via SSH au SBC atteint en moyenne 400 Ko / s, soit 3,2 Mo / s, un chiffre bien inférieur aux 24 Mo / s attendus.)
Pourquoi notre lien fonctionne-t-il à 13% de sa capacité?
Est-ce peut-être de notre /dev/urandom
faute?
# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]
Non, certainement pas.
Est-ce peut-être le SBC lui-même? Peut-être que c'est trop lent à traiter? Essayons d'exécuter la même commande SSH (c'est-à-dire l'envoi de données au SBC) mais cette fois à partir d'une autre machine (Machine 2) connectée via 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]
Non, cela fonctionne bien - le démon SSH sur le SBC peut (facilement) gérer les 11 Mo / s (c'est-à-dire les 100 Mo / s) fournis par sa liaison Ethernet.
Et le CPU du SBC est-il chargé en faisant cela?
Nan.
Donc...
- en termes de réseau (selon
iperf3
), nous devrions être en mesure de faire 10 fois la vitesse - notre CPU peut facilement supporter la charge
- ... et nous n'impliquons aucun autre type d'E / S (par exemple des disques).
Qu'est-ce qui se passe?
Netcat et ProxyCommand à la rescousse
Essayons de simples anciennes netcat
connexions - fonctionnent-elles aussi vite que prévu?
Dans le SBC:
# nc -l -p 9988 | pv -ptebar > /dev/null
Dans l'ordinateur portable:
# cat /dev/urandom | pv -ptebar | nc 192.168.1.150 9988
117MiB 0:00:33 [3.82MiB/s] [3.57MiB/s]
Ça marche! Et fonctionne à la vitesse attendue - bien meilleure, 10 fois meilleure -.
Alors, que se passe-t-il si j'exécute SSH à l'aide d'un ProxyCommand pour utiliser 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]
Travaux! Vitesse 10x.
Maintenant, je suis un peu confus - lorsque vous utilisez un "nu" nc
comme Proxycommand
, ne faites-vous pas exactement la même chose que SSH? c'est-à-dire créer un socket, se connecter au port 22 du SBC, puis pelleter le protocole SSH dessus?
Pourquoi y a-t-il cette énorme différence dans la vitesse résultante?
PS Ce n'était pas un exercice académique - ma borg
sauvegarde s'exécute 10 fois plus vite à cause de cela. Je ne sais juste pas pourquoi :-)
EDIT : Ajout d'une "vidéo" du processus ici . En comptant les paquets envoyés à partir de la sortie d'ifconfig, il est clair que dans les deux tests, nous envoyons 40 Mo de données, les transmettant dans environ 30 000 paquets - juste beaucoup plus lentement lorsque vous ne les utilisez pas ProxyCommand
.
nc
utilise la mise en mémoire tampon de ligne, alors qu'ilssh
n'a pas de mise en mémoire tampon. Donc (ou si c'est le cas) le trafic ssh implique plus de paquets.