Aus Gentoo Linux Wiki.
Der Inhalt stammt ursprünglich von http://de.gentoo-wiki.com/Schnelles_kopieren. Da die Datenbank des Gentoo Linux Wikis im Oktober 2009 verloren gegangen war (Meldung von dem Hauptadmin "Mikevalstar" vom 27.10.2009 auf http://de.gentoo-wiki.com/wiki/Hauptseite, mehr dazu unter http://gentoo-wiki.com/outage-10-08.html), kann ich die ursprüngliche Seite nicht mehr verlinken.
Durch Zufall habe ich aber eine lokale Kopie davon. Hier ist sie (wegen des anderen Wikis leicht umformatiert):
Um Dateien rekursiv von quelle1/ und quelle2/ nach ziel/ zu kopieren, benutzt man folgende Anweisung:
cp -Rv quelle1/ quelle2/ ziel/
cp kopiert Zeichen für Zeichen. Mit den Kernel-Pipes können Daten Block für Block kopiert werden. tar konvertiert Verzeichnisse und Dateien rekursiv in einen einzigen Datenstrom (stream). An einem Ende der Pipe werden Dateien und Verzeichnisse in einen Stream gepackt und am anderen entpackt.
# Kopieren mit tar: tar -c quelle1/ quelle2/ | tar -C ziel/ -xv
Das ist nicht unbedingt schneller aber flexibler. Das geht natürlich auch über ein Script:
# tcp (tar copy): #!/bin/bash tar -c $1 | tar -C $2 -xv
Man sollte beachten, dass ext2, ext3 und die meisten modernen Linux-Dateisysteme sog. sparse files besitzen. Diese Funktion wird benutzt, um große Dateien, deren Inhalt aus vielen Nullen besteht auf effiziente Weise zu speichern. Im Normalfall ist das nicht von Interesse, aber manche Programme nutzen die Funktion ausgiebig (z.B. net-p2p/mldonkey). Man sollte vorsichtig sein, wenn man solche Dateien mit dieser Methode kopiert, weil dies den verfügbaren Speicherplatz sprengen könnte. Während das Hilfsmittel cp 'sparse files' automatisch erkennt, tut tar dies nicht. 'Sparse files' aus dem Quellverzeichnis werden im Quellverzeichnis vollständig dargestellt, solange nicht das Flag -S auf der linken Seite der Pipe gesetzt wird.
Dateien werden gestreamt durch die Pipe an ssh geschickt, welches eine Verbindung aufbaut und dann entfernt einen Befehl ausführt der die Daten verarbeitet, in diesem Fall den Stream entpackt.
# Lokal zu entfernt: tar cv Dateiliste | ssh -C entfernter.rechner.de "tar x -C /home/user/Zielpfad"
# Lokal zu entfernt, mit schnellerer Verschlüsselung: tar cv Dateiliste | ssh -C -c blowfish entfernter.rechner.de "tar x -C /home/user/Zielpfad"
# Entfernt zu lokal: ssh -C entfernter.rechner.de "tar c -C Quellverzeichnis" |tar x -C Zielverzeichnis
Der ssh-Parameter -C ist schaltet dabei die Kompression des Datenstroms an und ist nicht in jedem Fall sinnvoll.
Zum einfachen kopieren von Files über SSH nutzt man scp:
# Entfernt zu lokal: scp -C entfernter_rechner:pfad/zur/quelldatei .
# Lokal zu entfernt: scp -C lokal1 lokal2 ... entfernter_rechner:pfad/zum/ziel/
Auch hier ist der Komprimierungsparameter -C wieder optional.
Datentransfer mit Netcat verursacht nur minimale CPU-Auslastungen gegenüber ssh. Das liegt daran, dass die Daten nicht verschlüsselt werden. Es findet auch keine Authentifizierung statt. Es wird einfach nur ein Port geöffnet und auf eine Verbindung gewartet.
Nachteile:
Beispiel:
# Ziel: user@zielrechner# nc -l -p 2342 | tar -C /ziel/verz –xz
# Quelle: user@quellrechner# tar -cz /quelle/verz | nc 192.168.0.2 2342
Um die CPU-Last weiter zu reduzieren, kann lzop anstelle der tar-Option z verwendet werden. lzop komprimiert wesentlich schneller aber weniger effizient:
Zielrechner: nc -l -p 2342 | lzop -d | tar -C /ziel/verz -x
Quellrechner: tar -c /quelle/verz | lzop | nc zielrechner 2342
Selbe Idee wie bei Netcat.
Zielrechner: socat -u - tcp4-listen:2342 | tar x -C /ziel/verz
Quellrechner: tar c /quelle/verz | socat -u - tcp4:zielrechner:2342
Wir können eine ganze Reihe von Kompressionsmethoden durch einen allgemeinen Aufruf verwenden:
Zielrechner: socat -u - tcp4-listen:2342 | ${UNZIP} | tar x -C /ziel/verz
Quellrechner: tar c /quelle/verz | ${ZIP} | socat -u - tcp4:zielrechner:2342
Wir definieren schließlich ZIP als einen der folgenden Befehle:
und UNZIP als:
Wo liegen die Unterschiede?
# Messvorrichtung: time -p tar /usr/src/linux-2.6.3 | ${ZIP} | cat > /dev/null
Programm | Daten | Laufzeit |
---|---|---|
cat | 182 MB | 1.1 sec |
lzop | 64 MB | 4 sec |
gzip –fast | 51 MB | 9 sec |
gzip | 41 MB | 18 sec |
gzip –best | 41 MB | 49 sec |
bzip2 | 32 MB | 134 sec |
Diese Einsparungen beim Komprimieren (bzw. beim Nicht-Komprimieren) sollten jedoch mit der vorhanden Bandbreite abgewogen werden. So macht es wenig Sinn, große Datenmengen unkomprimiert über eine DSL Leitung zu schicken - andererseits macht es aber wenig Sinn, nicht weiter komprimierbare Daten (z.B. JPEG/PNG-Bilder, AVIs, MP3s, zips, …) mit lzop/gzip/bzip2 nochmal zu "komprimieren". Hierdurch wird nur Rechenleistung verschwendet und somit u.U. ein geringerer Durchsatz erreicht.