Die TL; DR-Version
Sehen Sie sich diese ASCII-Besetzung oder dieses Video an und finden Sie Gründe, warum dies geschieht. Die folgende Textbeschreibung bietet mehr Kontext.
Details zum Setup
- Maschine 1 ist ein Arch Linux-Laptop, auf dem
ssh
eine Verbindung zu einem SBC (Orange PI Zero) hergestellt wird , auf dem Armbian ausgeführt wird. - Der SBC selbst ist über Ethernet mit einem DSL-Router verbunden und hat eine IP von 192.168.1.150
- Der Laptop ist über WLAN mit dem Router verbunden - mithilfe eines offiziellen Raspberry PI-WLAN-Dongles.
- Es gibt auch einen anderen Laptop (Maschine 2), der über Ethernet mit dem DSL-Router verbunden ist.
Benchmarking der Verknüpfung mit iperf3
Beim Benchmarking mit iperf3
liegt die Verbindung zwischen Laptop und SBC - wie erwartet - unter den theoretischen 56 MBit / s, da es sich um eine WiFi-Verbindung innerhalb eines sehr "überfüllten 2,4 GHz" (Wohnhaus) handelt .
Genauer gesagt: Nach dem Ausführen iperf3 -s
auf dem SBC werden die folgenden Befehle auf dem Laptop ausgeführt:
# 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
Das Hochladen auf den SBC erreicht also im Grunde genommen etwa 24 MBit / s, und das Herunterladen von ihm ( -R
) erreicht 32 MBit / s.
Benchmarking mit SSH
Vor diesem Hintergrund wollen wir sehen, wie SSH abschneidet. Ich habe erfahren zuerst die Probleme , die zu diesem Beitrag führt bei der Verwendung rsync
und borgbackup
- beide SSH als Transportschicht mit ... Lassen Sie sich also , wie SSH führt auf dem gleichen Link zu sehen:
# cat /dev/urandom | \
pv -ptebar | \
ssh [email protected] 'cat >/dev/null'
20.3MiB 0:00:52 [ 315KiB/s] [ 394KiB/s]
Nun, das ist eine miserable Geschwindigkeit! Deutlich langsamer als die erwartete Verbindungsgeschwindigkeit ...
(Falls Sie sich nicht bewusst sind pv -ptevar
: Es zeigt die aktuelle und durchschnittliche Datenrate an, die durch die Verbindung geht. In diesem Fall wird das Lesen von /dev/urandom
und Senden der Daten über SSH an den SBC festgestellt liegt im Durchschnitt bei 400 KB / s - das sind 3,2 MBit / s, weitaus weniger als die erwarteten 24 MBit / s.)
Warum ist unser Link zu 13% ausgelastet?
Ist es vielleicht unsere /dev/urandom
Schuld?
# cat /dev/urandom | pv -ptebar > /dev/null
834MiB 0:00:04 [ 216MiB/s] [ 208MiB/s]
Nein, definitiv nicht.
Ist es vielleicht die SBC selbst? Vielleicht ist es zu langsam zu verarbeiten? Versuchen wir, denselben SSH-Befehl auszuführen (dh Daten an den SBC zu senden), diesmal jedoch von einem anderen Computer (Computer 2), der über das Ethernet verbunden ist:
# cat /dev/urandom | \
pv -ptebar | \
ssh [email protected] 'cat >/dev/null'
240MiB 0:00:31 [10.7MiB/s] [7.69MiB/s]
Nein, das funktioniert einwandfrei - der SSH-Dämon auf dem SBC kann (leicht) die 11 MB / s (dh die 100 MB / s) verarbeiten, die die Ethernet-Verbindung bereitstellt.
Und ist dabei die CPU des SBC geladen?
Nee.
So...
- In
iperf3
Bezug auf das Netzwerk sollten wir in der Lage sein, die 10-fache Geschwindigkeit zu erreichen - Unsere CPU kann die Last problemlos aufnehmen
- ... und wir haben keine andere Art von E / A (z. B. Laufwerke).
Was zum Teufel ist los?
Netcat und ProxyCommand zur Rettung
Versuchen wir es mit einfachen alten netcat
Verbindungen. Laufen sie so schnell, wie wir es erwarten würden?
In der SBC:
# nc -l -p 9988 | pv -ptebar > /dev/null
Im Laptop:
# cat /dev/urandom | pv -ptebar | nc 192.168.1.150 9988
117MiB 0:00:33 [3.82MiB/s] [3.57MiB/s]
Es klappt! Und läuft mit der erwarteten - viel besseren, 10x besseren - Geschwindigkeit.
Was passiert also, wenn ich SSH mit einem ProxyCommand ausführe, um nc zu verwenden?
# cat /dev/urandom | \
pv -ptebar | \
ssh -o "Proxycommand nc %h %p" [email protected] 'cat >/dev/null'
101MiB 0:00:30 [3.38MiB/s] [3.33MiB/s]
Funktioniert! 10x Geschwindigkeit.
Jetzt bin ich ein wenig verwirrt - wenn ein „nackten“ kann nc
als ein Proxycommand
, nicht im Grunde Sie genau dasselbe zu tun , dass SSH tut? dh Erstellen eines Sockets, Verbinden mit dem Port 22 des SBC und anschließendes Verschieben des SSH-Protokolls?
Warum gibt es diesen großen Unterschied in der resultierenden Geschwindigkeit?
PS: Dies war keine akademische Übung. Mein borg
Backup läuft daher 10-mal schneller. Ich weiß nur nicht warum :-)
EDIT : ein „Video“ des Prozesses hinzugefügt hier . Zählt man die von der Ausgabe von ifconfig gesendeten Pakete, wird deutlich, dass wir in beiden Tests 40 MB Daten senden und diese in ungefähr 30 KB Paketen senden - nur viel langsamer, wenn wir sie nicht verwenden ProxyCommand
.
quelle
nc
verwendet Zeilenpufferung, währendssh
keine Pufferung hat. Also (oder wenn ja) beinhaltet der SSH-Verkehr mehr Pakete.Antworten:
Vielen Dank an die Leute, die Ideen in den Kommentaren eingereicht haben. Ich habe sie alle durchgesehen:
Aufzeichnen von Paketen mit tcpdump und Vergleichen der Inhalte in WireShark
Bei den aufgezeichneten Paketen war kein Unterschied von Bedeutung.
Überprüfung auf Traffic Shaping
Hatte keine Ahnung davon - aber nachdem ich mir die "tc" -Manpage angesehen hatte, konnte ich das überprüfen
tc filter show
gibt nichts zurücktc class show
gibt nichts zurücktc qdisc show
... gibt diese zurück:
... die nicht zwischen "ssh" und "nc" zu unterscheiden scheinen - in der Tat bin ich nicht einmal sicher, ob Traffic Shaping auf der Prozessebene funktionieren kann (ich würde erwarten, dass es auf Adressen / Ports / Differentiated funktioniert) Feld Dienste im IP-Header).
Debian Chroot, um potenzielle "Cleverness" im Arch Linux SSH-Client zu vermeiden
Nein, die gleichen Ergebnisse.
Endlich - Nagle
Durchführen einer Strace im Absender ...
... und als ich sah, was genau auf dem Socket passiert, über den die Daten übertragen werden, bemerkte ich dieses "Setup", bevor die eigentliche Übertragung beginnt:
Dadurch wird der SSH-Socket so eingerichtet, dass der Nagle-Algorithmus deaktiviert wird. Sie können googeln und alles darüber lesen - was jedoch bedeutet, dass SSH der Reaktionsfähigkeit Vorrang vor der Bandbreite einräumt -, weist es den Kernel an, alles, was auf diesen Socket geschrieben ist, sofort zu übertragen und nicht das Warten auf Bestätigungen von der Fernbedienung zu "verzögern".
Dies bedeutet im Klartext, dass SSH in seiner Standardkonfiguration KEINE gute Möglichkeit zum Transport von Daten ist - nicht, wenn die verwendete Verbindung langsam ist (was bei vielen WiFi-Verbindungen der Fall ist). Wenn wir Pakete über das Mobilfunknetz senden, die "meistens Header" sind, wird die Bandbreite verschwendet!
Um zu beweisen, dass dies tatsächlich der Schuldige war, habe ich LD_PRELOAD verwendet, um diesen speziellen Systemaufruf "fallen zu lassen":
Dort - perfekte Geschwindigkeit (na ja, genauso schnell wie iperf3).
Moral der Geschichte
Gib niemals auf :-)
Wenn Sie Tools wie
rsync
oder verwendenborgbackup
, die ihre Daten über SSH übertragen, und Ihre Verbindung langsam ist, versuchen Sie, SSH daran zu hindern, Nagle zu deaktivieren (wie oben gezeigt) - oder verwenden SieProxyCommand
, um SSH für die Verbindung über zu wechselnnc
. Dies kann in Ihrer $ HOME / .ssh / config automatisiert werden:... damit alle zukünftigen Verwendungen von "orangepi" als Ziel-Host in ssh / rsync / borgbackup fortan
nc
eine Verbindung herstellen (und Nagle daher in Ruhe lassen).quelle