Ich wollte einen Pfad von einem Computer in meinem Netzwerk zu einem anderen Computer im selben Netzwerk über eine 100-Mbit/s-Leitung sichern. Dafür habe ich getan
dd if=/local/path of=/remote/path/in/local/network/backup.img
das gab mir eine sehr niedrige Netzwerkübertragungsgeschwindigkeit von etwa 50 bis 100 kB/s, die ewig gedauert hätte. Also habe ich es gestoppt und beschlossen, es spontan zu zippen, um es viel kleiner zu machen, damit der zu übertragende Betrag geringer ist. So tat ich
dd if=/local/path | gzip > /remote/path/in/local/network/backup.img.gz
Aber jetzt bekomme ich so etwas wie 1 MB/s Netzwerkübertragungsgeschwindigkeit, also einen Faktor 10 bis 20 schneller. Nachdem ich das bemerkt hatte, testete ich es auf mehreren Pfaden und Dateien, und es war immer dasselbe.
Warum erhöht Piping dd
durch gzip
auch die Übertragungsraten um einen großen Faktor, anstatt nur die Bytelänge des Streams um einen großen Faktor zu reduzieren? Ich hatte stattdessen aufgrund des höheren CPU-Verbrauchs beim Komprimieren sogar einen kleinen Rückgang der Übertragungsraten erwartet, aber jetzt bekomme ich ein doppeltes Plus. Nicht, dass ich nicht glücklich wäre, aber ich wundere mich nur. ;)
dd
verwendet standardmäßig eine sehr kleine Blockgröße - 512 Bytes (!!). Das heißt, viele kleine Lese- und Schreibvorgänge. Es scheint, dass dd
, in Ihrem ersten Beispiel naiv verwendet, eine große Anzahl von Netzwerkpaketen mit einer sehr kleinen Nutzlast generiert hat, wodurch der Durchsatz verringert wurde.
Andererseits ist gzip
intelligent genug, um E/A mit größeren Puffern durchzuführen. Das heißt, eine kleinere Anzahl großer Schreibvorgänge über das Netzwerk.
Können Sie dd
noch einmal mit einem größeren bs=
-Parameter versuchen und sehen, ob es diesmal besser funktioniert?
Ein bisschen spät dazu, aber könnte ich hinzufügen ...
In einem Interview wurde ich einmal gefragt was wäre die schnellste Methode zum Klonen von Bit-für-Bit-Daten und grob mit der Verwendung von dd
oder dc3dd
beantwortet ( DoD funded ). Der Interviewer bestätigte, dass die Weiterleitung von dd
zu dd
effizienter ist, da dies einfach gleichzeitiges Lesen/Schreiben oder programmiertechnisch stdin/stdout
zulässt, was letztendlich die Schreibgeschwindigkeit und die Halbierungsübertragungszeit verdoppelt.
dc3dd verb=on if=/media/backup.img | dc3dd of=/dev/sdb
Cong ist richtig. Sie streamen die Blöcke von der unkomprimierten Festplatte auf einen Remote-Host. Ihre Netzwerkschnittstelle, Ihr Netzwerk und Ihr Remote-Server sind die Einschränkung. Zuerst müssen Sie die Leistung von DD steigern. Wenn Sie einen bs = -Parameter angeben, der am Plattenpufferspeicher ausgerichtet ist, wird die beste Leistung von der Platte erzielt. Sagen Sie zum Beispiel bs = 32M. Dadurch wird der gzip-Puffer mit der SATA- oder SAS-Zeilenrate aus dem Laufwerkspuffer gefüllt. Die Festplatte ist eher für sequenzielle Übertragungen geeignet, um einen besseren Durchsatz zu erzielen. Gzip komprimiert die Daten im Stream und sendet sie an Ihren Standort. Wenn Sie NFS verwenden, kann die NFS-Übertragung minimal sein. Wenn Sie SSH verwenden, übernehmen Sie den SSH-Kapselungs- und Verschlüsselungsaufwand. Wenn Sie Netcat verwenden, haben Sie keine zusätzliche Verschlüsselung.
Ich gehe davon aus, dass die "Übertragungsgeschwindigkeit", auf die Sie sich beziehen, von dd
gemeldet wird. Dies ist tatsächlich sinnvoll, dadd
tatsächlich das 10-fache der Datenmenge pro Sekunde überträgt ! dd
überträgt jedoch nicht über das Netzwerk - dieser Auftrag wird vom gzip
-Prozess verarbeitet.
Ein wenig Kontext: gzip
verbraucht Daten aus seiner Eingabe-Pipe, so schnell es den internen Puffer leeren kann. Die Geschwindigkeit, mit der der Puffer von gzip
geleert wird, hängt von einigen Faktoren ab:
In diesem Fall kann das Netzwerk also 100 kB/s verarbeiten, und gzip
komprimiert die Daten um 10: 1 (und wird von der CPU nicht beeinträchtigt). Dies bedeutet, dass gzip
während der Ausgabe von 100kB/s verbrauchen 1MB/s kann und die Verbrauchsrate diejenige ist, die dd
sehen kann.