Il modo migliore per copiare milioni di file tra 2 server


39

Ho circa 5 milioni di piccoli file (5-30k) in una singola directory che vorrei copiare su un'altra macchina sulla stessa rete gigabit. Ho provato a usare rsync, ma rallenterebbe fino a una scansione dopo alcune ore di funzionamento, presumo a causa del fatto che rsync deve controllare il file di origine e destinazione ogni volta?

Il mio secondo pensiero sarebbe quello di usare SCP, ma volevo ottenere opinioni esterne per vedere se c'era un modo migliore. Grazie!


Il collo di bottiglia è probabilmente il filesystem sul lato ricevente. La maggior parte dei filesystem finirà per essere esponenzialmente più lenta quanto più file metterai in una singola directory (cioè ogni volta che rsync aggiunge un nuovo file sul lato ricevente, il lato ricevente rallenta per la parte rimanente del trasferimento). Molti file system meno recenti non possono nemmeno contenere più di 32 KB di file in una singola directory.
Mikko Rantalainen,

Risposte:


41

Qualcosa del genere dovrebbe funzionare bene:

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

Forse ometti anche gzip e la bandiera "z" per l'estrazione, dal momento che sei su una rete gigabit.


È necessario decomprimerlo o ssh comprime comunque lo stream? O può essere fatto per farlo?
Thilo,

1
ssh comprime il flusso se si passa "-C". Su una lan non mi preoccuperei di comprimere il flusso; su Internet probabilmente lo farei, a meno che non fosse già compresso.

6
Personalmente lascerei gzip attivo: anche su Ethernet gigabit è molto improbabile che il collo di bottiglia sia la CPU.
Benji XVI,

6
@BenjiXVI il collo di bottiglia sarà sicuramente la CPU come gzipverrà eseguito solo su un singolo core. Ci si può ragionevolmente aspettare circa 30 MB / s con il livello di compressione predefinito di 6 - ma questo non ottimizzerà al massimo Gigabit Ethernet.
syneticon-dj,

2
usare pbzip2? ...
Apache,

19

Sono sicuro che il fatto che tu abbia tutti i CINQUE MILIONI di file in una singola directory genererà molti strumenti. Non mi sorprende che rsync non abbia gestito questo con garbo - è una situazione piuttosto "unica". Se riuscissi a trovare un modo per strutturare i file in una sorta di struttura di directory, sono sicuro che gli strumenti di sincronizzazione standard come rsync sarebbero molto più reattivi.

Tuttavia, solo per dare alcuni consigli concreti, forse una soluzione sarebbe quella di spostare temporaneamente l'unità fisicamente nella macchina di destinazione in modo da poter fare una copia dei file nel server effettivo (non in rete). Quindi, spostare indietro l'unità e utilizzare rsync per mantenere le cose aggiornate.


6
+1 per spostarsi fisicamente in auto, è molto più veloce in questo modo
Robert Gould,

1
Di sicuro batte tutto copiando su un jump drive e andando avanti e indietro ...
VirtuosiMedia

@RobertGould Usiamo IPoAC come protocollo di trasmissione: "D
coolcat007

12

Per copiare milioni di file su uno switch gigabit (in un ambiente attendibile) puoi anche usare una combinazione di netcat (or nc)e tar, come già suggerito dall'utente55286. Questo eseguirà lo streaming di tutti i file come un unico file di grandi dimensioni (vedi Fast File Copy - 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 questi giorni con sempre più cose che provano prima IPv6 potrebbe essere necessario utilizzare anche l'opzione -4 con il comando nc su entrambe le estremità per farlo funzionare su una "vecchia" LAN IPv4.
BeowulfNode42,

5

Avevamo circa 1 milione di file in una directory (circa 4 anni di file).

E abbiamo usato robocopy per spostare i file nella directory YYYY / MM (circa 35-45.000 file al mese) .. abbiamo inserito lo script robocopy in un file .bat come questo:

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

brevi note .. /ns /nc /nfl /npè per evitare di gonfiare il file di registro con informazioni aggiuntive /log+...è di scrivere informazioni di riepilogo nel file di registro.

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

quindi ad esempio i file modificati> = 01 / Nov / 2008 (inclusi) in file modificati <01 / Dec / 2008 (non inclusi)

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 per spostare i file

quindi arriva la directory di origine

quindi arriva la directory di destinazione (le directory verranno create al volo come e quando richiesto).

Ci sono voluti circa 40 - 60 minuti per 1 mese di trasferimento (circa 35-45.000 file) Riteniamo che occorrano circa 12 ore o meno per 1 anno di trasferimento.

Utilizzando Windows Server 2003.

Tutto il materiale è registrato nel file di registro ... Ora inizio, Ora fine e Numero di file copiati.

Robocopy ha salvato la giornata.


robocopy in questi giorni ha l'opzione / MT [: n] per Esegui copie multi-thread con n thread (impostazione predefinita 8) per ottenere lo stesso effetto solo meglio e non fare affidamento sugli intervalli di date e consente una singola riga di comando, anziché una per filo. Sebbene l'interruttore MT non sia disponibile su Windows 2003.
BeowulfNode42

4

Sai, ho fatto +1 sulla soluzione tar, ma - a seconda dell'ambiente - c'è un'altra idea che si verifica. Potresti pensare di usare dd (1) . Il problema della velocità con qualcosa del genere è che ci vogliono molti movimenti della testa per aprire e chiudere un file, cosa che farai cinque milioni di volte. Se tu potessi assicurarti che questi siano assegnati in modo contiguo, potresti invece dd, il che ridurrebbe il numero di movimenti della testa di un fattore di 5 o più.


4

Preferisco usare lz4 come strumento di compressione più veloce al momento. L'opzione SSH -c arcfour128 utilizza un algoritmo di crittografia più veloce del valore predefinito. [1]

Quindi il trasferimento di directory è simile al seguente:

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

Si noti che su Debian il comando lz4 è lz4c e su CentOS è lz4.


La crittografia / decrittografia ssh può essere un collo di bottiglia a causa dell'utilizzo della cpu nella cpu di origine o destinazione e della natura a thread singolo di quasi tutte le implementazioni di ssh. È una LAN Gigabit privata, quindi non è necessario crittografare.
BeowulfNode42,

3

Robocopy è ottimo per cose come questa. Proverà di nuovo dopo i timeout di rete e ti permetterà anche di impostare un ritardo tra i pacchetti per ora inondare il tubo.

[Modificare]

Si noti che questa è un'applicazione solo per Windows.


Supponendo che tu sia su Windows ovviamente. La cosa bella di robocopy è che l'app è responsabile dell'iterazione dei file. Il problema con utils unix è che potresti esaurire lo spazio della shell espandendo i nomi.
Martin Beckett,

3

So che potrebbe essere stupido, ma hai pensato di copiarli su un disco esterno e trasferirli sull'altro server? In realtà potrebbe essere la soluzione più efficiente e semplice.


3

Stiamo esaminando questo problema al momento. Dobbiamo trasferire circa 18 milioni di piccoli file, per un totale di circa 200 GB. Abbiamo ottenuto le migliori prestazioni utilizzando la vecchia XCopy, ma ci è voluto ancora molto tempo. Circa 3 giorni da 1 server a un altro, circa 2 settimane a un'unità esterna!

Attraverso un altro processo, dovevamo duplicare il server. Questo è stato fatto con Acronis. Ci sono volute circa 3 ore !!!

Lo esamineremo ancora. Il suggerimento dd sopra probabilmente fornirebbe risultati simili.


2

Già tonnellate di buoni suggerimenti, ma volevo aggiungere Beyond Compare . Di recente ho trasferito circa 750.000 file tra 5 KB e 20 MB da un server all'altro tramite uno switch gigabit. Non ha nemmeno avuto alcun singhiozzo. Concesso, ci è voluto del tempo, ma me lo sarei aspettato con così tanti dati.



1

Comprimili in un singolo file prima di copiarlo, quindi scompattali nuovamente dopo averlo copiato.


1

In una situazione simile, ho provato a utilizzare tar per raggruppare i file. Ho scritto un piccolo script per reindirizzare l'output del comando tar direttamente alla macchina di destinazione direttamente in un processo di ricezione tar che separava i file.

L'approccio tar ha quasi raddoppiato la velocità di trasferimento rispetto a scp o rsync (YMMV).

Ecco i comandi tar. Nota che dovrai abilitare i comandi r creando file .rhosts nelle directory home di ogni macchina (rimuovili dopo che la copia è completa - sono noti problemi di sicurezza). Si noti inoltre che, come al solito, HP-UX è scomodo, mentre il resto del mondo usa "rsh" per il comando della shell remota, HP-UX usa "remsh". 'rsh' è una specie di shell limitata nel linguaggio HP.

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

Il primo comando tar crea un file chiamato '-', che in questo caso è un token speciale che significa 'output standard'. L'archivio creato contiene tutti i file nella directory corrente (.) Più tutte le sottodirectory (tar è ricorsivo per impostazione predefinita). Questo file di archivio viene reindirizzato al comando remsh che lo invia alla macchina box2. Nella casella 2 prima cambio nella directory di ricezione corretta, quindi estraggo da "-" o "input standard" i file in arrivo.

Ho avuto 6 di questi comandi tar in esecuzione contemporaneamente per garantire che il collegamento di rete fosse saturo di dati, anche se sospetto che l'accesso al disco possa essere stato il fattore limitante.


1

Bypassa il filesystem.

Sei in grado di smontare questa partizione in cui vivono i file o montarla in sola lettura? Fallo, quindi qualcosa del tipo:

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

È quindi possibile montare diskimage.bincome dispositivo di loopback sul lato di destinazione e copiarne i file sul proprio file system di destinazione oppure utilizzare gli strumenti appropriati per ricucirlo in una partizione vuota sul lato di destinazione (pericoloso, ma probabilmente possibile , anche se non l'ho mai fatto.)

Se sei davvero coraggioso, puoi ddfarlo direttamente in una partizione sul lato destinazione. Non lo consiglio.


0

puoi provare quanto segue (potrebbe essere in lotti di file)

  • tar il batch di file
  • decomprimili
  • copia usando scp se possibile
  • gunzip
  • decomprimere i file

0

Come suggerito da sth potresti provare tar over ssh.

Se non hai bisogno della crittografia (originariamente hai usato rsync, ma non hai detto che era rsync + ssh) puoi provare tar su netcat per evitare il sovraccarico di ssh.

Naturalmente puoi anche abbreviare il tempo impiegato usando gzip o altri metodi di compressione.


0

C'è qualcos'altro da considerare. Prova questo:

  • Crea un disco rigido virtuale, dimensionato dinamicamente
  • Montalo, possibilmente come directory
  • Imposta l'attributo 'comprimi tutto il disco'

In questo modo, non vi è alcun sovraccarico per l'iterazione o la compressione della directory, poiché ciò è stato fatto al momento della scrittura dei file. C'è solo un file da spostare: il disco rigido virtuale.

Su Windows, ho impostato la dimensione del pacchetto TCP predefinito su un valore maggiore, ad esempio 16348. Ciò significa meno sovraccarico dell'intestazione IP.

Una cosa in cui mi sono imbattuto, tuttavia, è che è meglio mantenere file di dimensioni inferiori a 100 Mb per un trasferimento di rete o USB. Uso Rar.exe per questo - per suddividere i file.

Funziona come un campione. Questo è l'equivalente di 'dd' in Linux .. Il concetto di montare un filesystem compresso in una directory è normale anche per Linux, quindi si applica la stessa logica. Dovresti assicurarti che tutti i file siano chiusi prima dell'inizio dell'operazione, come negli altri metodi.

Ciò ha l'ulteriore vantaggio di consentire di inserire una quota di dimensioni in una cartella. Se il disco rigido virtuale ha dimensioni fisse, il superamento di tale limite non comporta la chiusura del server, ma causa solo un errore durante la creazione o la scrittura del file.

Un disco rigido virtuale formattato come NTFS può gestire anche milioni di file in una cartella.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.