Copia file parallela


9

Ho un elenco di file che devo copiare su un sistema Linux: ogni file ha dimensioni comprese tra 10 e 100 GB.

Voglio solo copiare sul filesystem locale. C'è un modo per farlo in parallelo - con più processi ciascuno responsabile della copia di un file - in modo semplice ?

Posso facilmente scrivere un programma multithread per farlo, ma sono interessato a scoprire se esiste un metodo Linux di basso livello per farlo.


1
La copia di file paralleli non comporterà una notevole accelerazione. (Almeno in teoria non dovrebbe.)
Tarnay Kálmán,


1
@ TarnayKálmán a meno che non si disponga di un file system in stile cluster, overlay, RAID o "impavido" o di uno qualsiasi dei precedenti su una rete relativamente alta latenza o occupata; o un carico di lavoro in cui la latenza per file è una parte significativa del tempo di copia per quel file (1e5 + file molto piccoli, backend indirizzati al contenuto, ecc.). L'elaborazione simultanea sarebbe estremamente utile in tali situazioni.
valore

Risposte:


11

Se il tuo sistema non viene danneggiato da esso (ad esempio, forse i file sono nella cache), GNU Parallel http://www.gnu.org/software/parallel/ potrebbe funzionare per te:

find . -print0 | parallel -0 -j10 cp {} destdir

Questo eseguirà 10 messaggi simultanei cp.

Pro: è semplice da leggere.

Contro: GNU Parallel non è standard sulla maggior parte dei sistemi, quindi probabilmente è necessario installarlo.

Guarda il video introduttivo per maggiori informazioni: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Vedi anche https://oletange.wordpress.com/2015/07/04/parallel-disk-io-is-it-faster/ per una discussione sull'I / O del disco parallelo.


3

Non esiste un meccanismo di basso livello per questo per un motivo molto semplice: farlo distrugge le prestazioni del sistema. Con le unità disco ogni scrittura contenderà il posizionamento della testa, portando a una massiccia attesa di I / O. Con gli SSD, questo finirà per saturare uno o più bus di sistema, causando altri problemi.


Err che al momento non sembra essere il caso di un singolo cp, sono sicuro che ci sia un mezzo felice per più "cp" paralleli in cui il tuo canale I / O non diventa completamente saturo ...
Jon,

1
Un autobus saturo è un autobus felice. La larghezza di banda inattiva è una larghezza di banda sprecata.
valore

3

Come accennato, questa è un'idea terribile. Ma credo che tutti dovrebbero essere in grado di attuare i propri piani orribili, quindi ...

for FILE in *;do cp $FILE <destination> &;done

L'asterisco può essere sostituito con un'espressione regolare dei tuoi file, o $(cat <listfile>)se li hai tutti in un documento di testo. La e commerciale inizia un comando in background, quindi il ciclo continuerà, generando più copie.

Come accennato, questo annichilerà completamente il tuo IO. Quindi ... non consiglierei davvero di farlo.

--Christopher Karel


3

L'unica risposta che non distruggerà la capacità di risposta della tua macchina non è esattamente una "copia", ma è molto veloce. Se non modificherai i file nella nuova o vecchia posizione, un hard link è effettivamente come una copia e (solo) se sei nello stesso filesystem, vengono creati molto molto velocemente.

Dai un'occhiata cp -le vedi se funzionerà per te.


2

Ecco uno strumento di copia file distribuito / parallelo e decentralizzato che bloccherà il file e copierà tutti i blocchi in parallelo. Probabilmente ti aiuterà solo se hai un SSD che supporta più flussi o una sorta di installazione con più testine del disco.

https://github.com/hpc/dcp


1

Per le persone che pensano che non sia una grande idea, direi che dipende. Puoi avere un grande sistema raid o un filesystem parallelo che fornirà prestazioni davvero migliori di quelle che un processo cp può gestire. Quindi sì, è necessario utilizzare uno "strumento parallelo".

Facciamo questo esempio:

timeout 10 strace -e write -c cp /dev/zero /dev/null
strace: Process 24187 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.655188           4    166222           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.655188                166222           total

Poi questo

timeout 0.01 strace -e write  cp /dev/zero /dev/null
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
strace: Process 24567 detached

quindi ogni scrittura di syscall fatta da "cp" in questo caso è di 64 KiB e per 10 secondi sul mio sistema sono in grado di fornire questa larghezza di banda: 65536 * 166222/10 = 1089352499 = ~ 1,08 GB / s

Ora, lanciamo questo carico di lavoro con 2 processi (ho 4 core ma il mio desktop è usato per altre cose, e qui è solo un esempio):

timeout 10 strace -e write -c cp /dev/zero /dev/null & timeout 10 strace -e write -c cp /dev/zero /dev/null &  wait
[1] 26106
[2] 26107
strace: Process 26113 detached
strace: Process 26112 detached
% time     seconds  usecs/call     calls    errors syscall
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
------ ----------- ----------- --------- --------- ----------------
100.00    0.624108           4    162616           write
100.00    0.638468           4    162451           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.624108                162616           total
100.00    0.638468                162451           total
------ ----------- ----------- --------- --------- ----------------
[1]-  Exit 124                timeout 10 strace -e write -c cp /dev/zero /dev/null

Quindi vediamo che siamo in grado di raddoppiare le prestazioni usando 2 core per lanciarlo.

Quindi, se siamo in un contesto diverso dall'unità 1xHard all'unità 1xHard ma da un array raid (o più NVMe, quindi non è il caso più comune, ma ci lavoro su questo ogni giorno), mostra sicuramente una prestazione migliore per usare più comuni in parallelo.


-1

Dovresti provare questo:

    $ seq 3 | parallel cp -v / etc / passwd passwd {}

Questo copierà il file passwd 3 volte dalla directory / etc / nella tua $ HOME

O se il tuo file è nella tua home directory

    $ seq 3 | parallel cp -v passwd {, {}}

Questo copierà il file passwd 3 volte nel tuo $ HOME

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.