Qual è il modo migliore per eseguire una copia parallela su Unix?


18

Devo sistematicamente copiare il contenuto di una cartella su un file system di rete sul mio computer locale. Ci sono molti file (1000) nella cartella remota che sono tutti relativamente piccoli ma a causa dell'overhead di rete una copia normale cp remote_folder/* ~/local_folder/richiede molto tempo (10 minuti).

Credo che sia perché i file vengono copiati in sequenza: ogni file attende fino al termine del precedente prima dell'inizio della copia.

Qual è il modo più semplice per aumentare la velocità di questa copia? (Suppongo che sia per eseguire la copia in parallelo.)

La compressione dei file prima della copia non accelererà necessariamente le cose perché potrebbero essere tutte salvate su dischi diversi su server diversi.


La compressione dei file prima della copia accelererà enormemente le cose perché non ci sarà più bisogno di "hai preso quel file", "sì, l'ho fatto", "ecco il prossimo", "ok", ... Sono quelli "inversioni di tendenza" che ti rallentano.
David Schwartz,

Probabilmente è la velocità del disco, piuttosto che la velocità della rete, che è il tuo fattore limitante e, in tal caso, farlo per file in parallelo renderà l'operazione più lenta , non più veloce, perché costringerai il disco a cercare continuamente avanti e indietro tra i file.
Joel Coehoorn,

Mentre zippare potrebbe non essere una buona idea (l'esecuzione di un algoritmo di compressione su oltre 1000s di file potrebbe richiedere un po 'di tempo), tar potrebbe essere praticabile.
Rob,

@JoelCoehoorn, ci sono casi in cui questo non è il caso: ad es. Più mandrini + piccoli file (o semplicemente letture casuali). In questo scenario, "parallel cp" sarebbe di aiuto.
CAFxX,

Risposte:


8

Finché limiterai i comandi di copia che stai eseguendo, probabilmente potresti usare uno script come quello pubblicato da Scrutinizer

SOURCEDIR="$1"
TARGETDIR="$2"
MAX_PARALLEL=4
nroffiles=$(ls "$SOURCEDIR" | wc -w)
setsize=$(( nroffiles/MAX_PARALLEL + 1 ))
ls -1 "$SOURCEDIR"/* | xargs -n "$setsize" | while read workset; do
  cp -p "$workset" "$TARGETDIR" &
done
wait

1
Nota di avvertimento: questo script si interrompe con nomi di file contenenti spazi o caratteri globbing.
slhck,

@OldWolf - Puoi spiegare come funziona questo script? Ad esempio, quale parte ha la parallelizzazione?
DSG

3
@dsg: il &alla fine del cpcomando consente al whileciclo di continuare e avviare il comando cp successivo senza attendere. Il xargscomando passa i nomi dei file in gruppi di 4 (MAX_PARALLEL) al whileloop.
RedGrittyBrick

Non ha funzionato per me. Non sono sicuro che sia possibile accelerare cp. Ovviamente puoi velocizzare il calcolo attraverso il multithreading. Ma non credo che lo stesso valga per la gestione dei dati del disco rigido.
Adobe,

9

Se hai GNU Parallel http://www.gnu.org/software/parallel/ installato puoi farlo:

parallel -j10 cp {} destdir/ ::: *

Puoi installare GNU Parallel semplicemente:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh

Guarda i video introduttivi di GNU Parallel per saperne di più: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1


3

Un modo sarebbe usare rsync che copierà solo le modifiche: nuovi file e parti modificate di altri file.

http://linux.die.net/man/1/rsync

L'esecuzione di qualsiasi forma di operazione di copia parallela probabilmente inonderà la tua rete e l'operazione di copia si interromperà o soffrirà di colli di bottiglia sul disco di origine o di destinazione.


2

Onestamente, lo strumento migliore è gsutil di Google. Gestisce copie parallele con ricorsione della directory. La maggior parte degli altri metodi che ho visto non è in grado di gestire la ricorsione della directory. Non menzionano specificamente il filesystem locale nelle copie del filesystem locale nei loro documenti, ma funziona come un incantesimo.

È un altro binario da installare, ma probabilmente uno che potresti già eseguire considerando l'adozione di tutti i servizi cloud al giorno d'oggi.


2

Rsync parallelo usando find:

export SOURCE_DIR=/a/path/to/nowhere
export DEST_DIR=/another/path/to/nowhere

# sync folder structure first
rsync -a -f'+ */' -f'- *' $SOURCE_DIR $DEST_DIR

# cwd
cd $SOURCE_DIR

# use find to help filter files etc. into list and pipe into gnu parallel to run 4 rsync jobs simultaneously
find . -type f | SHELL=/bin/sh parallel --linebuffer --jobs=4 'rsync -av {} $DEST_DIR/{//}/'

su una LAN aziendale, single rsync fa circa 800 Mbps; con 6-8 lavori sono in grado di superare i 2,5 Gbps (a spese del carico elevato). Limitato dai dischi.


0

Ci sono molte cose che potresti dover considerare a seconda della topologia che hai. Ma prima di iniziare a pensare a soluzioni complesse, potresti semplicemente provare a dividere l'attività in due lavori e verificare se il tempo necessario ridurrà in modo significativo:

La prossima volta prova:

  cp remote_folder/[a-l]* ~/local_folder/ &
  cp remote_folder/[!a-l]* ~/local_folder/ &
  wait
  wait

(potresti voler sostituire [al] * con qualcos'altro che corrisponde a circa la metà dei file - forse [0-4] * - a seconda del contenuto della cartella)

Se il tempo non migliora drasticamente, potrebbe essere più importante verificare se è necessario copiare tutti i file (qual è il rapporto tra i file modificati e tutti i file?)

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.