Parallelizza rsync usando GNU Parallel


18

Ho usato uno rsyncscript per sincronizzare i dati su un host con i dati su un altro host. I dati hanno numerosi file di piccole dimensioni che contribuiscono a quasi 1,2 TB.

Per sincronizzare quei file, ho usato il rsynccomando come segue:

rsync -avzm --stats --human-readable --include-from proj.lst /data/projects REMOTEHOST:/data/

I contenuti di proj.lst sono i seguenti:

+ proj1
+ proj1/*
+ proj1/*/*
+ proj1/*/*/*.tar
+ proj1/*/*/*.pdf
+ proj2
+ proj2/*
+ proj2/*/*
+ proj2/*/*/*.tar
+ proj2/*/*/*.pdf
...
...
...
- *

Come test, ho raccolto due di questi progetti (8,5 GB di dati) e ho eseguito il comando sopra. Essendo un processo sequenziale, si completa con 14 minuti e 58 secondi. Pertanto, per 1,2 TB di dati occorrerebbero diverse ore.

Se potessi più rsyncprocessi in parallelo (usando &, xargso parallel), mi farebbe risparmiare tempo.

Ho provato con il comando seguente con parallel(dopo aver cdeseguito l'installazione nella directory dei sorgenti) e ci sono voluti 12 minuti e 37 secondi per eseguire:

parallel --will-cite -j 5 rsync -avzm --stats --human-readable {} REMOTEHOST:/data/ ::: .

Ciò avrebbe dovuto richiedere 5 volte meno tempo, ma non è stato così. Penso, sto sbagliando da qualche parte.

Come posso eseguire più rsyncprocessi per ridurre i tempi di esecuzione?


1
Sei limitato dalla larghezza di banda della rete? Ips del disco? Larghezza di banda del disco?
Ole Tange,

Se possibile, vorremmo utilizzare il 50% della larghezza di banda totale. Ma parallelizzare più rsyncs è la nostra prima priorità.
Mandar Shinde,

Puoi farci sapere il tuo: larghezza di banda di rete, Ips di disco, larghezza di banda del disco e larghezza di banda effettivamente utilizzata?
Ole Tange,

In realtà, non conosco i parametri sopra. Per il momento, possiamo trascurare la parte di ottimizzazione. Più rsyncs in parallelo è l'obiettivo principale ora.
Mandar Shinde,

Non ha senso andare in parallelo se la limitazione non è la CPU. Può anche peggiorare le cose (movimenti del braccio del disco in conflitto sul disco sorgente o di destinazione).
xenoide,

Risposte:


16

I seguenti passaggi hanno fatto il lavoro per me:

  1. Esegui il rsync --dry-runprimo per ottenere l'elenco dei file interessati.
$ rsync -avzm --stats --safe-links --ignore-existing --dry-run \
    --human-readable /data/projects REMOTE-HOST:/data/ > /tmp/transfer.log
  1. Ho alimentato l'output di cat transfer.logto parallelper eseguire 5 rsyncs in parallelo, come segue:
$ cat /tmp/transfer.log | \
    parallel --will-cite -j 5 rsync -avzm --relative \
      --stats --safe-links --ignore-existing \
      --human-readable {} REMOTE-HOST:/data/ > result.log

Qui, l' --relativeopzione ( collegamento ) ha assicurato che la struttura della directory per i file interessati, alla fonte e alla destinazione, rimanga la stessa (all'interno della /data/directory), quindi il comando deve essere eseguito nella cartella sorgente (ad esempio /data/projects).


5
Ciò farebbe un rsync per file. Probabilmente sarebbe più efficiente dividere l'intero elenco di file usando splite inoltrando quei nomi di file in parallelo. Quindi utilizzare rsync --files-fromper estrarre i nomi dei file da ciascun file e sincronizzarli. rm backup. * split -l 3000 backup.list backup. Sono i backup. * | parallel --line-buffer --verbose -j 5 rsync --progress -av --files-from {} / LOCAL / PARENT / PATH / REMOTE_HOST: REMOTE_PATH /
Sandip Bhattacharya

1
In che modo il secondo comando rsync gestisce le righe in result.log che non sono file? vale a dire receiving file list ... done created directory /data/.
Mike D,

1
Nelle versioni più recenti di rsync (3.1.0+), è possibile utilizzare --info=nameal posto di -ve otterrai solo i nomi dei file e delle directory. Potresti voler usare --protect-args anche nel trasferimento "interno" di rsync se qualche file può contenere spazi o metacaratteri della shell.
Ghepardo,

13

Personalmente uso questo semplice:

ls -1 | parallel rsync -a {} /destination/directory/

Il che è utile solo quando hai più di alcune directory non quasi vuote, altrimenti finirai per avere quasi tutte le rsyncterminazioni e l'ultima che fa tutto il lavoro da sola.


Funziona benissimo - difficile sapere se sta facendo qualcosa, quindi un -v al parallelo lo rende più loquace. Inoltre, -j da 30 a parallelo (cioè prima del comando rsync) fa funzionare 30 lavori, non solo uno per core della CPU, che è l'impostazione predefinita.
Criggie il

12

Scoraggerei fortemente chiunque dall'utilizzare la risposta accettata, una soluzione migliore è quella di eseguire la scansione della directory di livello superiore e avviare un numero proporzionale di operazioni di rincronizzazione.

Ho un grande volume zfs e la mia fonte era un mount cifs. Entrambi sono collegati con 10G e in alcuni benchmark possono saturare il collegamento. Le prestazioni sono state valutate utilizzando zpool iostat 1.

L'unità sorgente è stata montata come:

mount -t cifs -o username=,password= //static_ip/70tb /mnt/Datahoarder_Mount/ -o vers=3.0

Utilizzando un singolo rsyncprocesso:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/ /StoragePod

l'indicatore io legge:

StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.61K      0   130M
StoragePod  30.0T   144T      0  1.62K      0   130M

Questo nei benchmark sintetici (disco di cristallo), le prestazioni per la scrittura sequenziale si avvicinano a 900 MB / s, il che significa che il collegamento è saturo. 130 MB / s non è molto buono e la differenza tra l'attesa di un fine settimana e due settimane.

Quindi, ho creato l'elenco dei file e ho provato a eseguire nuovamente la sincronizzazione (ho una macchina a 64 core):

cat /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount.log | parallel --will-cite -j 16 rsync -avzm --relative --stats --safe-links --size-only --human-readable {} /StoragePod/ > /home/misha/Desktop/rsync_logs_syncs/Datahoarder_Mount_result.log

e ha avuto la stessa performance!

StoragePod  29.9T   144T      0  1.63K      0   130M
StoragePod  29.9T   144T      0  1.62K      0   130M
StoragePod  29.9T   144T      0  1.56K      0   129M

In alternativa, ho semplicemente eseguito rsync nelle cartelle principali:

rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/Marcello_zinc_bone /StoragePod/Marcello_zinc_bone
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/fibroblast_growth /StoragePod/fibroblast_growth
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/QDIC /StoragePod/QDIC
rsync -h -v -r -P -t /mnt/Datahoarder_Mount/Mikhail/sexy_dps_cell /StoragePod/sexy_dps_cell

Ciò ha effettivamente aumentato le prestazioni:

StoragePod  30.1T   144T     13  3.66K   112K   343M
StoragePod  30.1T   144T     24  5.11K   184K   469M
StoragePod  30.1T   144T     25  4.30K   196K   373M

In conclusione, come ha fatto notare @Sandip Bhattacharya, scrivi una piccola sceneggiatura per ottenere le directory e parallelamente. In alternativa, passare un elenco di file a rsync. Ma non creare nuove istanze per ogni file.


5

Un modo testato per eseguire rsync parallelizzato è: http://www.gnu.org/software/parallel/man.html#EXAMPLE:-Parallelizing-rsync

rsync è un ottimo strumento, ma a volte non riempie la larghezza di banda disponibile. Questo è spesso un problema quando si copiano diversi file di grandi dimensioni su connessioni ad alta velocità.

Di seguito verrà avviato un rsync per file di grandi dimensioni in src-dir in dest-dir sul server fooserver:

cd src-dir; find . -type f -size +100000 | \
parallel -v ssh fooserver mkdir -p /dest-dir/{//}\; \
  rsync -s -Havessh {} fooserver:/dest-dir/{} 

Le directory create potrebbero finire con autorizzazioni errate e i file più piccoli non vengono trasferiti. Per correggere quelli eseguono rsync un'ultima volta:

rsync -Havessh src-dir/ fooserver:/dest-dir/ 

Se non sei in grado di inviare i dati, ma devi estrarli e i file sono chiamati digits.png (ad es. 000000.png) potresti essere in grado di fare:

seq -w 0 99 | parallel rsync -Havessh fooserver:src/*{}.png destdir/

Qualche altra alternativa per evitare find?
Mandar Shinde,

1
Limita il -maxdepth di find.
Ole Tange,

Se uso l' --dry-runopzione in rsync, avrei un elenco di file che verrebbero trasferiti. Posso fornire tale elenco di file parallelper parallelizzare il processo?
Mandar Shinde

1
file cat | parallel -v ssh fooserver mkdir -p / dest-dir / {//} \; rsync -s -Havessh {} fooserver: / dest-dir / {}
Ole Tange

Puoi per favore spiegare la mkdir -p /dest-dir/{//}\;parte? Soprattutto la {//}cosa è un po 'confusa.
Mandar Shinde,

1

Per le sincronizzazioni multi destinazione, sto usando

parallel rsync -avi /path/to/source ::: host1: host2: host3:

Suggerimento: tutte le connessioni ssh vengono stabilite con le chiavi pubbliche in ~/.ssh/authorized_keys


1

Ho sempre cercato Google parallel rsync poiché dimentico sempre il comando completo, ma nessuna soluzione ha funzionato per me come volevo - o include più passaggi o deve essere installato parallel. Ho finito con questo one-liner per sincronizzare più cartelle:

find dir/ -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo dir/%/ host:/dir/%/)'

-P 5 è la quantità di processi che vuoi generare - usa 0 per un numero illimitato (ovviamente non raccomandato).

--bwlimit per evitare di usare tutta la larghezza di banda.

-I %argomento fornito da find (directory trovata in dir/)

$(echo dir/%/ host:/dir/%/)- stampa le directory di origine e di destinazione che vengono lette da rsync come argomenti. % è sostituito da xargscon il nome della directory trovato da find.

Supponiamo che io abbia due directory in /home: dir1e dir2. Io corro find /home -type d|xargs -P 5 -I % sh -c 'rsync -a --delete --bwlimit=50000 $(echo /home/%/ host:/home/%/)'. Quindi il comando rsync verrà eseguito come due processi (due processi perché /homeha due directory) con i seguenti argomenti:

rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
rsync -a --delete --bwlimit=50000 /home/dir1/ host:/home/dir1/
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.