Der beste Weg, um Millionen von Dateien zwischen 2 Servern zu kopieren


39

Ich habe ungefähr 5 Millionen kleine (5-30k) Dateien in einem einzigen Verzeichnis, die ich auf einen anderen Computer im selben Gigabit-Netzwerk kopieren möchte. Ich habe versucht, rsync zu verwenden, aber es würde sich nach ein paar Stunden Durchforsten verlangsamen. Ich gehe davon aus, dass rsync jedes Mal die Quell- und Zieldatei überprüfen muss.

Mein zweiter Gedanke wäre, scp zu verwenden, aber ich wollte eine externe Meinung einholen, um zu sehen, ob es einen besseren Weg gibt. Vielen Dank!


Der Engpass ist wahrscheinlich das Dateisystem auf der Empfängerseite. Die meisten Dateisysteme werden exponentiell langsamer, je mehr Dateien Sie in einem einzelnen Verzeichnis ablegen (dh jedes Mal, wenn rsync eine neue Datei auf der Empfängerseite hinzufügt, verlangsamt sich die Empfängerseite für den verbleibenden Teil der Übertragung). Viele ältere Dateisysteme können nicht einmal mehr als 32 KB-Dateien in einem einzigen Verzeichnis enthalten.
Mikko Rantalainen

Antworten:


41

So etwas sollte gut funktionieren:

tar c some/dir | gzip - |  ssh host2 tar xz

Vielleicht lassen Sie auch gzip und das "z" -Flag für die Extraktion weg, da Sie sich in einem Gigabit-Netzwerk befinden.


Muss es gzip sein oder komprimiert ssh den Stream trotzdem? Oder kann dafür gesorgt werden?
Thilo

1
ssh komprimiert den Stream, wenn Sie "-C" übergeben. Über ein LAN würde ich mich nicht darum kümmern, den Stream zu komprimieren. über das internet würde ich wohl, wenn es nicht schon komprimiert wäre.

6
Persönlich würde ich gzip eingeschaltet lassen: Selbst über Gigabit-Ethernet ist es sehr unwahrscheinlich, dass der Engpass die CPU ist.
Benji XVI

6
@BenjiXVI der Engpass wird sicherlich die CPU sein, da gzipimmer nur auf einem einzigen Kern ausgeführt wird. Mit der Standardkomprimierungsstufe von 6 können Sie mit ungefähr 30 MB / s rechnen - dies wird jedoch Gigabit-Ethernet nicht ausreizen.
Syneticon-DJ

2
pbzip2 benutzen? ...
Apache

19

Ich bin mir sicher, dass die Tatsache, dass Sie alle FÜNF MILLIONEN Dateien in einem einzigen Verzeichnis haben, viele Tools in einen Strudel werfen wird. Ich bin nicht überrascht, dass rsync dies nicht ordnungsgemäß handhabt - es ist eine ganz "einzigartige" Situation. Wenn Sie einen Weg finden könnten, die Dateien in eine Art Verzeichnisstruktur zu strukturieren, wären die Standard-Synchronisierungstools wie rsync sicher viel reaktionsschneller.

Nur um einige konkrete Ratschläge zu geben - möglicherweise besteht eine Lösung darin, das Laufwerk vorübergehend physisch in den Zielcomputer zu verschieben, damit Sie eine Kopie der Dateien auf dem tatsächlichen Server (nicht über das Netzwerk) erstellen können. Verschieben Sie dann das Laufwerk zurück und verwenden Sie rsync, um die Dinge auf dem neuesten Stand zu halten.


6
+1 für die Bewegung fahren physisch, es ist viel schneller auf diese Weise
Robert Gould

1
Es ist sicher besser, als alles auf einer Sprungfahrt zu kopieren und hin und her zu gehen ...
VirtuosiMedia

@RobertGould Verwenden wir IPoAC als Übertragungsprotokoll: "D
coolcat007

12

Zum Kopieren von Millionen von Dateien über einen Gigabit-Switch (in einer vertrauenswürdigen Umgebung) können Sie auch eine Kombination aus netcat (or nc)und verwenden tar, wie bereits von user55286 vorgeschlagen. Dadurch werden alle Dateien als eine große Datei gestreamt (siehe Schnelle Dateikopie - Linux! (39 GB) ).

# requires netcat on both servers
nc -l -p 2342 | tar -C /target/dir -xzf -   # destination box
tar -cz /source/dir | nc Target_Box 2342    # source box

In diesen Tagen, in denen immer mehr Dinge zuerst IPv6 ausprobieren, müssen Sie möglicherweise auch den Schalter -4 mit Ihrem Befehl nc an beiden Enden verwenden, damit es in einem "alten" IPv4-LAN funktioniert.
BeowulfNode42

5

Wir hatten ungefähr 1 Million Dateien in einem Verzeichnis (im Wert von ungefähr 4 Jahren).

Und wir haben Robocopy verwendet, um Dateien in das YYYY / MM-Verzeichnis zu verschieben (ca. 35-45.000 Dateien pro Monat). Wir haben das Robocopy-Skript in eine .bat-Datei wie diese geschrieben:

ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20081101 /MINAGE:20081201 /MOV H:\Cs\out\fix H:\BCK_REPORT\2008\11
ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20081201 /MINAGE:20090101 /MOV H:\Cs\out\fix H:\BCK_REPORT\2008\12
ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20090101 /MINAGE:20090201 /MOV H:\Cs\out\fix H:\BCK_REPORT\2009\01
ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20090201 /MINAGE:20090301 /MOV H:\Cs\out\fix H:\BCK_REPORT\2009\02

kurze Notizen .. /ns /nc /nfl /npsoll verhindern, dass die Protokolldatei mit zusätzlichen /log+...Informationen überfüllt wird.

/minage and /maxage is to copy files modified with in that date range. 

so zum Beispiel Dateien geändert> = 01 / Nov / 2008 (inklusive) zu Dateien geändert <01 / Dec / 2008 (nicht inklusive)

ROBOCOPY /NS /NC /NFL /NP /LOG+:H:\BCK_REPORT\ROBO.LOG /MAXAGE:20081101 /MINAGE:20081201 /MOV H:\Cs\out\fix H:\BCK_REPORT\2008\11

/mov um die Dateien zu verschieben

dann kommt quellverzeichnis

Dann kommt das Zielverzeichnis (Verzeichnisse werden bei Bedarf im laufenden Betrieb erstellt).

Es dauerte ungefähr 40 - 60 Minuten für eine Übertragung im Wert von 1 Monat (ungefähr 35-45.000 Dateien). Wir rechnen mit ungefähr 12 Stunden oder weniger für eine Übertragung im Wert von 1 Jahr.

Verwenden von Windows Server 2003.

Das gesamte Material wird in der Protokolldatei protokolliert ... Startzeit, Endzeit und Anzahl der kopierten Dateien.

Robocopy rettete den Tag.


Heutzutage bietet robocopy den Schalter / MT [: n] für die Ausführung von Multithread-Kopien mit n Threads (Standard 8), um den gleichen Effekt nur besser und nicht abhängig von Datumsbereichen zu erzielen. Statt einer einzigen Befehlszeile kann auch eine verwendet werden pro Faden. Der MT-Schalter ist unter Windows 2003 nicht verfügbar.
BeowulfNode42

4

Weißt du, ich habe die Teerlösung um 1 erhöht, aber je nach Umgebung gibt es noch eine andere Idee. Möglicherweise möchten Sie dd (1) verwenden . Das Problem mit der Geschwindigkeit besteht darin, dass zum Öffnen und Schließen einer Datei viele Kopfbewegungen erforderlich sind, die Sie fünf Millionen Mal ausführen werden. Wenn Sie sicherstellen möchten, dass diese fortlaufend zugewiesen werden, können Sie sie stattdessen hinzufügen, wodurch die Anzahl der Kopfbewegungen um den Faktor 5 oder mehr verringert wird.


4

Ich bevorzuge derzeit die Verwendung von lz4 als schnellstes Komprimierungswerkzeug. Die SSH-Option -c arcfour128 verwendet einen schnelleren Verschlüsselungsalgorithmus als die Standardeinstellung. [1]

Die Verzeichnisübertragung sieht also ungefähr so ​​aus:

tar -c folder | lz4 -c | ssh -carcfour128 somehost 'lz4 -d | tar -x > folder'

Bitte beachten Sie, dass unter Debian der Befehl lz4c und unter CentOS lz4 ist.


Die Verschlüsselung / Entschlüsselung von ssh kann ein Engpass sein, da die CPU entweder auf der Quell- oder der Ziel-CPU verwendet wird und nahezu alle ssh-Implementierungen Single-Threaded-fähig sind. Es ist ein privates Gigabit-LAN, sodass keine Verschlüsselung erforderlich ist.
BeowulfNode42

3

Robocopy eignet sich hervorragend für solche Dinge. Nach einem Netzwerk-Timeout wird es erneut versucht. Außerdem können Sie eine Verzögerung zwischen den Paketen festlegen, um die Pipe jetzt zu überfluten.

[Bearbeiten]

Beachten Sie, dass dies eine reine Windows-Anwendung ist.


Angenommen, Sie arbeiten mit Windows. Das Schöne an Robocopy ist, dass die App für das Durchlaufen der Dateien verantwortlich ist. Das Problem bei Unix-Utils ist, dass der Shell-Speicherplatz zur Neige geht und die Namen erweitert werden.
Martin Beckett

3

Ich weiß, dass das vielleicht dumm ist - aber haben Sie daran gedacht, sie einfach auf eine externe Festplatte zu kopieren und auf den anderen Server zu übertragen? Es kann tatsächlich die effizienteste und einfachste Lösung sein.


3

Wir untersuchen dieses Problem derzeit. Wir müssen ungefähr 18 Millionen kleine Dateien übertragen - insgesamt ungefähr 200 GB. Wir haben die beste Leistung mit normalem XCopy erzielt, aber es hat noch lange gedauert. Ungefähr 3 Tage von einem Server zu einem anderen, ungefähr 2 Wochen zu einem externen Laufwerk!

Durch einen anderen Prozess mussten wir den Server duplizieren. Dies wurde mit Acronis gemacht. Es hat ungefähr 3 Stunden gedauert !!!

Wir werden dies weiter untersuchen. Der obige dd-Vorschlag würde wahrscheinlich ähnliche Ergebnisse liefern.


2

Schon jede Menge guter Vorschläge, wollte aber Beyond Compare reinwerfen . Ich habe kürzlich ungefähr 750.000 Dateien zwischen 5 KB und 20 MB über einen Gigabit-Switch von einem Server auf einen anderen übertragen. Es gab nicht einmal Schluckauf. Zugegeben, es hat eine Weile gedauert, aber ich würde das mit so vielen Daten erwarten.


1

Ich würde sehen, wie ein zip-> copy-> unzip durchgeführt wird

oder was auch immer Ihr bevorzugtes Komprimierungs- / Archivierungssystem ist.


Ja, sie in eine Datei zu komprimieren wäre auch eine gute Idee
Robert Gould

sogar nur ein Tarball
Joel Coehoorn

1

Packen Sie sie in eine einzelne Datei, bevor Sie sie kopieren, und entpacken Sie sie anschließend erneut.


1

In einer ähnlichen Situation habe ich versucht, die Dateien mit tar zu stapeln. Ich habe ein winziges Skript geschrieben, um die Ausgabe des tar-Befehls direkt an den Zielcomputer zu leiten und an einen empfangenden tar-Prozess weiterzuleiten, der die Dateien entbündelt.

Der tar-Ansatz hat die Übertragungsrate im Vergleich zu scp oder rsync (YMMV) fast verdoppelt.

Hier sind die tar-Befehle. Beachten Sie, dass Sie r-Befehle aktivieren müssen, indem Sie .rhosts-Dateien in den Basisverzeichnissen jedes Computers erstellen (entfernen Sie diese nach Abschluss des Kopiervorgangs - es handelt sich um berüchtigte Sicherheitsprobleme). Beachten Sie auch, dass HP-UX wie üblich umständlich ist - während der Rest der Welt für den Remote-Shell-Befehl 'rsh' verwendet, verwendet HP-UX 'remsh'. 'rsh' ist eine Art eingeschränkte Shell im HP-Sprachgebrauch.

box1> cd source_directory; tar cf - . | remsh box2 "cd target_directory; tar xf - "

Mit dem ersten Befehl tar wird eine Datei mit dem Namen '-' erstellt. Hierbei handelt es sich um ein spezielles Token, das in diesem Fall 'Standardausgabe' bedeutet. Das erstellte Archiv enthält alle Dateien im aktuellen Verzeichnis (.) Sowie alle Unterverzeichnisse (tar ist standardmäßig rekursiv). Diese Archivdatei wird in den Befehl remsh weitergeleitet, der sie an die Box2-Maschine sendet. In Box 2 wechsle ich zuerst in das richtige Empfangsverzeichnis und extrahiere dann aus '-' oder 'Standardeingabe' die eingehenden Dateien.

Ich hatte 6 dieser tar-Befehle gleichzeitig ausgeführt, um sicherzustellen, dass die Netzwerkverbindung mit Daten gesättigt war, obwohl ich vermute, dass der Festplattenzugriff der begrenzende Faktor gewesen sein könnte.


1

Umgehen Sie das Dateisystem.

Können Sie die Bereitstellung dieser Partition aufheben, auf der sich die Dateien befinden, oder sie schreibgeschützt bereitstellen? Tun Sie das, dann etwas wie:

dd if=/dev/PARTITION | ssh username@host "dd of=diskimage.bin"

Sie können dann diskimage.binals Loopback-Gerät auf der Zielseite einbinden und Dateien daraus in Ihr tatsächliches Zieldateisystem kopieren oder die richtigen Tools verwenden, um sie wieder in eine leere Partition auf der Zielseite einzubinden (gefährlich, aber wahrscheinlich möglich) , obwohl ich es noch nie gemacht habe.)

Wenn Sie wirklich mutig sind, können Sie ddes direkt zurück in eine Partition auf der Zielseite. Das empfehle ich nicht.


0

Sie können Folgendes versuchen (möglicherweise in Stapel von Dateien)

  • tar den Stapel von Dateien
  • gzip sie
  • wenn möglich mit scp kopieren
  • gunzip
  • entpacken Sie die Dateien

0

Wie von etw vorgeschlagen, könnte man es mit tar over ssh versuchen.

Wenn Sie keine Verschlüsselung benötigen (ursprünglich haben Sie rsync verwendet, aber nicht erwähnt, dass es sich um rsync + ssh handelt), können Sie tar over netcat ausprobieren, um den ssh-Overhead zu vermeiden.

Sie können die benötigte Zeit natürlich auch mit gzip oder einer anderen Komprimierungsmethode verkürzen.


0

Es gibt noch etwas zu beachten. Versuche dies:

  • Erstellen Sie eine VHD mit dynamischer Größe
  • Hängen Sie es ein, möglicherweise als Verzeichnis
  • Legen Sie das Attribut "Gesamte Festplatte komprimieren" fest

Auf diese Weise entsteht KEIN Overhead für die Verzeichnisiteration oder -komprimierung, da dies zum Zeitpunkt des Schreibens der Dateien erfolgte. Es muss nur eine Datei verschoben werden - die VHD.

Unter Windows habe ich die Standard-TCP-Paketgröße auf 16348 festgelegt. Dies bedeutet weniger IP-Header-Overhead.

Eine Sache, auf die ich gestoßen bin, ist, dass es am besten ist, die Dateigröße für eine Netzwerk- oder USB-Übertragung unter 100 MB zu halten. Ich benutze dafür Rar.exe - um die Dateien aufzuteilen.

Funktioniert wie ein Champion. Dies ist das Äquivalent von 'dd' in Linux. Das Konzept, ein komprimiertes Dateisystem in ein Verzeichnis zu mounten, ist auch für Linux normal, daher gilt dieselbe Logik. Sie sollten sicherstellen, dass alle Dateien geschlossen sind, bevor der Vorgang gestartet wird, wie bei den anderen Methoden.

Dies hat den zusätzlichen Vorteil, dass Sie einem Ordner ein Größenkontingent zuweisen können. Wenn die VHD eine feste Größe hat und dieses Limit überschritten wird, wird der Server nicht heruntergefahren. Es wird lediglich ein Fehler beim Erstellen oder Schreiben der Datei verursacht.

Eine als NTFS formatierte VHD kann auch Millionen von Dateien in einem Ordner verarbeiten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.