Was ist der schnellste Weg, um unter Linux eine Million Bilder von einem Verzeichnis in ein anderes zu verschieben?

14

Ich habe eine Million Images, die 30 GB Speicherplatz beanspruchen und von einem lokalen Verzeichnis in ein anderes lokales Verzeichnis verschoben werden müssen.

Was wäre der effizienteste Weg, dies zu tun? Verwenden mv? Verwenden cp? Verwenden rsync? Etwas anderes?

Ich muss diese nehmen:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

und bewege sie hierher:

/path/to/new/img/dir/
Ryan
quelle
5
Ich glaube nicht, dass Sie die mvLeistung übertreffen können , wenn sich sowohl das Quell- als auch das Zielverzeichnis im selben Dateisystem befinden.
Frédéric Hamidi

Antworten:

25

rsync Dies wäre eine schlechte Wahl, da viele Client- / Server-Hintergrundarbeiten ausgeführt werden, die sowohl lokale als auch Remote-Systeme berücksichtigen.

mvist wahrscheinlich die beste Wahl. Wenn möglich, sollten Sie es mv directory_old directory_newlieber versuchen als mv directory_old/* directory_new/. Auf diese Weise bewegen Sie eine Sache anstelle von einer Million Dingen.

Richard
quelle
6
+1 für den Rat, die Verzeichnisse anstelle der Dateien zu verschieben.
Ex Umbris
4
Außerdem würde die Wildcard-Erweiterung wahrscheinlich die maximalen Argumente brechen, die mvvon Millionen unterstützt werden.
Slhck
6
rsync verarbeitet Übertragungen auf lokalen Speichermedien einwandfrei. Es erzwingt Dinge wie --whole-file (Entfernen der Implementierung des Delta-Xfer-Algorithmus) und verhindert andere Dinge wie --komprimierung, die bei lokalen Übertragungen keinen Zweck erfüllen. Wenn sich die Verzeichnisse auf verschiedenen Dateisystemen befinden, bietet 'mv' keinerlei Leistung. Wenn sie sich auf demselben Dateisystem befinden, dann "mv" nur die Verzeichnisse wie diese Leute sagten.
UtahJarhead
Wenn viele Bilder vorhanden sind, wird bei Verwendung eines einfachen Shell-Platzhalters die maximale Befehlszeile überlaufen.
Raúl Salinas-Monteagudo
1
Beim Verschieben zwischen Datenträgern werden weiterhin alle Daten verschoben. Auf derselben Festplatte werden mvnur die Inode-Informationen aktualisiert, sodass sie mv directory_old directory_newschneller funktionieren alsmv directory_old/* directory_new
Anshul
14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Dadurch wird die Argumenterweiterung nicht überlaufen.
  • Sie können die Dateierweiterung angeben, wenn Sie möchten. (-Name ...)
  • find -print0Mit xargs -0können Sie Leerzeichen in den Namen verwenden.
  • xargs -rwird nur ausgeführt, mvwenn etwas verschoben werden muss. ( mvwird sich beschweren, wenn keine Quelldateien angegeben sind).
  • Mit der Syntax mv -tkönnen Sie zuerst das Ziel und dann die Quelldateien angeben, die von benötigt werden xargs.
  • Das Verschieben des gesamten Verzeichnisses ist natürlich viel schneller, da es unabhängig von der Anzahl der darin enthaltenen Dateien in konstanter Zeit erfolgt, aber:
    • Das Quellverzeichnis verschwindet für einen Bruchteil der Zeit und kann zu Problemen führen.
    • Wenn der Prozess das aktuelle Verzeichnis als Ausgabeverzeichnis verwendet (im Gegensatz dazu, dass immer auf einen vollständigen Pfad von einem nicht verschobenen Speicherort verwiesen wird), müssen Sie ihn neu starten. (wie bei der Protokollrotation ).

Übrigens würde ich mich fragen, ob ich wirklich so viele Dateien gleichzeitig verschieben muss. Die Stapelverarbeitung wird überbewertet. Ich versuche, keine großen Mengen an Arbeit anzusammeln, wenn ich Dinge in dem Moment verarbeiten kann, in dem sie generiert werden.

Raúl Salinas-Monteagudo
quelle
Dies funktioniert gut genug, um Dateien über Dateisysteme auf demselben Server zu verschieben. Gut genug, dass ich mich nicht darum gekümmert habe, nach einer Lösung in rsync zu suchen. Sicher, es hat ein oder zwei Stunden gedauert, aber es funktioniert. Eine Sache zu beachten, wenn Sie anstelle von "." Einen Verzeichnisnamen suchen. - Verwenden Sie unbedingt den abschließenden Schrägstrich im Befehl find, da sonst das Verzeichnis am Ziel des Befehls mv neu erstellt wird.
Speeddymon
7

Wenn sich die beiden Verzeichnisse im selben Dateisystem befinden, verwenden Sie mvdas VERZEICHNIS und nicht den Inhalt des Verzeichnisses.

Wenn sie sich auf zwei verschiedenen Dateisystemen befinden, verwenden Sie rsync:

rsync -av /source/directory/ /destination

Beachten Sie das Nachlaufen /der Quelle. Dies bedeutet, dass der INHALT des Verzeichnisses und nicht das Verzeichnis selbst kopiert wird. Wenn Sie diese Option /deaktivieren, werden die Dateien weiterhin kopiert, sie befinden sich jedoch in einem Verzeichnis mit dem Namen /destination/directory. Mit dem / werden die Dateien nur in/destination

rsyncbehält den Dateibesitz bei, wenn Sie ihn als root ausführen oder wenn die Dateien Ihnen gehören. Es wird auch die mtimevon jeder einzelnen Datei verwaltet.

UtahJarhead
quelle
2
Beim Kopieren eines großen Ordners von einer Festplatte auf eine andere Festplatte rsyncscheinen Kreise herumzulaufen mv. Danke für den Tipp!
Leo-the-Manic
2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

Wenn Sie 'cp' verwenden, führt jede Datei ein Öffnen-Lesen-Schließen-Öffnen-Schreiben-Schließen durch. Tar verwendet verschiedene Verfahren zum Lesen und Schreiben sowie mehrere Schritte, um mehrere Dateien gleichzeitig zu bearbeiten. Selbst auf einer einzelnen CPU-Box sind Multithread-Apps schneller.

Maholt
quelle
2
Dies könnte zwar die Frage beantworten, aber es wäre eine bessere Antwort, wenn Sie eine Erklärung dafür liefern könnten .
DavidPostill
1
Wenn sie sich auf dem lokalen Computer befinden, befinden sie sich wahrscheinlich im selben Dateisystem. Durch die Verwendung erhalten tar c | tar xSie Kosten von O (total_size) anstelle von O (file_count).
Raúl Salinas-Monteagudo
1

Da beide directory_old und directory_new im gleichen Dateisystem ist , könnten Sie verwenden , cp -lanstatt mvals eine Option. cp -lerstellt einen festen Link zu den Originaldateien. Wenn Sie mit 'Verschieben' fertig sind und mit dem Ergebnis zufrieden sind, können Sie diese Dateien aus directory_old entfernen. In Bezug auf die Geschwindigkeit ist es dasselbe wie 'mv', wenn Sie zuerst die Links erstellen und dann die ursprünglichen entfernen. Mit diesem Ansatz können Sie jedoch von vorne beginnen, wenn dies sinnvoll ist

Serge
quelle
0

Es kommt darauf an (tm). Wenn Ihr Dateisystem Copy-on-Write ist, sollte Copy ( cpoder rsynczum Beispiel) mit einem Umzug vergleichbar sein. In den meisten Fällen ist move ( mv) jedoch am schnellsten, da einfach die Daten umgeschaltet werden können, die beschreiben, wo eine Datei abgelegt wird (Hinweis: Dies ist zu stark vereinfacht).

Bei einer durchschnittlichen Linux-Installation würde ich mich also entscheiden mv.

EDIT: @ Frédéric Hamidi hat einen guten Punkt in den Kommentaren: Dies ist nur gültig, wenn beide auf dem gleichen Dateisystem und der gleichen Festplatte sind. Andernfalls werden die Daten trotzdem kopiert.

Carlpett
quelle
0

Um mindestens ~ 10k Dateien (keine Verzeichnisse) zu kopieren, beschwerte sich cp mit:

/ bin / cp kann nicht ausgeführt werden: Argumentliste zu lang

Die beste Option ist Rsync:

rsync Quellziel

Und es war sehr schnell erledigt!

Nico
quelle
0

Wenn Sie über freien Speicherplatz verfügen, archivieren Sie diese in einer einzelnen .tar-Datei (ohne schnellere Komprimierung), verschieben Sie diese Datei und entfernen Sie die Archivierung.

Endolith
quelle
0

Die Art des Ziels würde den effizientesten Weg für diese Aufgabe bestimmen. Nehmen wir an , Sie auf einem lokalen System sind, Ihr PWDist /gerade jetzt. und /aenthält die Millionen von Bildern. Unsere Aufgabe ist es, alle Bilder zu verschieben /bund dabei die gesamte Unterverzeichnisstruktur beizubehalten. Nehmen wir an , auch /aund /bPunkte sind Halterung für zwei verschiedene Partitionen, die jeweils auf einem lokal angeschlossenen Festplatte. Wir möchten diese Aufgabe mit einer Plane erledigen. Dies könnte einige Zeit dauern, so stellen Sie sicher , dass Sie verwenden screen, tmuxoder Sie ausführen dieses als Hintergrundprozess.

tar -C /a -cf . | tar -C /b -xf -

Das würde kopieren Sie alle Dateien und Verzeichnisse in /azu /b, so jetzt müssen Sie bis reinigen , /asobald Sie bestätigen es ohne Fehler beendet.

JM Becker
quelle