Copie de fichiers parallèle


9

J'ai une liste de fichiers que je dois copier sur un système Linux - chaque fichier varie de 10 à 100 Go.

Je veux seulement copier sur le système de fichiers local. Existe-t-il un moyen de le faire en parallèle - avec plusieurs processus chargés chacun de copier un fichier - de manière simple ?

Je peux facilement écrire un programme multithread pour ce faire, mais je suis intéressé à savoir s'il existe une méthode Linux de bas niveau pour le faire.


1
La copie de fichiers en parallèle n'apportera pas d'accélération significative. (
Du


1
@ TarnayKálmán, sauf si vous disposez d'un système de fichiers de type cluster, superposition, RAID ou "sans peur", ou tout ce qui précède sur un réseau à latence relativement élevée ou occupé; ou une charge de travail où la latence par fichier représente une partie importante du temps de copie de ce fichier (1e5 + très petits fichiers, backends adressés au contenu, etc.). Un traitement simultané serait extrêmement utile dans de telles situations.
rvalue

Réponses:


11

Si votre système n'est pas détruit par lui (par exemple, peut-être que les fichiers sont dans le cache), GNU Parallel http://www.gnu.org/software/parallel/ peut fonctionner pour vous:

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

Cela exécutera 10 cps simultanés .

Pro: C'est simple à lire.

Con: GNU Parallel n'est pas standard sur la plupart des systèmes - vous devez donc probablement l'installer.

Regardez la vidéo d'introduction pour plus d'informations: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Voir aussi https://oletange.wordpress.com/2015/07/04/parallel-disk-io-is-it-faster/ pour une discussion sur les E / S disque parallèles.


3

Il n'y a pas de mécanisme de bas niveau pour cela pour une raison très simple: cela détruira les performances de votre système. Avec les lecteurs de plateau, chaque écriture se disputera le placement de la tête, ce qui entraînera une attente d'E / S massive. Avec les SSD, cela finira par saturer un ou plusieurs de vos bus système, provoquant d'autres problèmes.


Euh, cela ne semble pas être le cas avec un seul cp actuellement, je suis sûr qu'il existe un juste milieu pour plusieurs "cp" parallèles sur lesquels votre canal d'E / S ne devient pas complètement saturé ...
Jon

1
Un bus saturé est un bus heureux. La bande passante inactive est une bande passante gaspillée.
rvalue

3

Comme mentionné, c'est une idée terrible. Mais je crois que tout le monde devrait pouvoir mettre en œuvre ses propres plans horribles, sooo ...

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

L'astérisque peut être remplacé par une expression régulière de vos fichiers, ou $(cat <listfile>)si vous les avez tous dans un document texte. L'esperluette lance une commande en arrière-plan, de sorte que la boucle continuera, générant plus de copies.

Comme mentionné, cela annihilera complètement votre E / S. Alors ... je ne recommanderais vraiment pas de le faire.

--Christopher Karel


3

La seule réponse qui ne gâchera pas la réactivité de votre machine n'est pas exactement une «copie», mais elle est très rapide. Si vous ne modifiez pas les fichiers dans le nouvel ou l'ancien emplacement, alors un lien dur est effectivement comme une copie, et (seulement) si vous êtes sur le même système de fichiers, ils sont créés très très très rapidement.

Vérifiez cp -let voyez si cela fonctionnera pour vous.


2

Voici un outil de copie de fichiers distribué / parallèle et décentralisé qui fragmentera le fichier et copiera tous les morceaux en parallèle. Cela ne vous aidera probablement que si vous avez un SSD qui prend en charge plusieurs flux ou une sorte de configuration avec plusieurs têtes de disque.

https://github.com/hpc/dcp


1

Pour les gens qui pensent que ce n'est pas une bonne idée, je dirais que cela dépend. Vous pouvez avoir un gros système de raid ou un système de fichiers parallèle qui offrira des performances vraiment meilleures qu'un processus cp peut gérer. Alors oui, vous devez utiliser un "outil parallèle".

Prenons cet exemple:

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

ensuite ceci

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

donc chaque écriture syscall effectuée par "cp" dans ce cas est de 64 Ko et pendant 10 secondes sur mon système, je suis en mesure de fournir cette bande passante: 65536 * 166222/10 = 1089352499 = ~ 1,08 Go / s

Maintenant, lançons cette charge de travail avec 2 processus (j'ai 4 cœurs mais mon bureau est utilisé pour d'autres choses, et ici ce n'est qu'un exemple):

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

Nous voyons donc que nous pouvons presque doubler les performances en utilisant 2 cœurs pour lancer cela.

Donc, si nous sommes dans un contexte différent du lecteur 1xHard au lecteur 1xHard mais d'un tableau RAID (ou de plusieurs NVMe, donc pas le cas le plus courant, je suis d'accord mais je travaille dessus tous les jours), cela montre certainement une meilleure performance pour utiliser plusieurs communs dans parallèle.


-1

Vous devriez essayer ceci:

    $ seq 3 | cp parallèle -v / etc / passwd passwd {}

Cela copiera le fichier passwd 3 fois depuis le répertoire / etc / vers votre $ HOME

Ou si votre fichier est dans votre répertoire personnel

    $ seq 3 | cp -v parallèle passwd {, {}}

Cela copiera le fichier passwd 3 fois dans votre $ HOME

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.