Quelle est la meilleure façon d'effectuer une copie parallèle sur Unix?


18

Je dois régulièrement copier le contenu d'un dossier sur un système de fichiers réseau sur mon ordinateur local. Il existe de nombreux fichiers (1 000) sur le dossier distant qui sont tous relativement petits, mais en raison de la surcharge du réseau, une copie régulière cp remote_folder/* ~/local_folder/prend beaucoup de temps (10 minutes).

Je pense que c'est parce que les fichiers sont copiés séquentiellement - chaque fichier attend que le précédent soit terminé avant de commencer la copie.

Quelle est la manière la plus simple d'augmenter la vitesse de cette copie? (Je suppose que c'est pour effectuer la copie en parallèle.)

Le fait de compresser les fichiers avant de les copier n'accélérera pas nécessairement les choses car ils peuvent tous être enregistrés sur des disques différents sur des serveurs différents.


Zipper les fichiers avant de les copier accélérera massivement car il n'y aura plus besoin "avez-vous obtenu ce fichier", "oui, je l'ai fait", "voici le suivant", "d'accord", ... Ce sont ceux-là "retournements" qui vous ralentissent.
David Schwartz

C'est probablement la vitesse du disque, plutôt que la vitesse du réseau, qui est votre facteur limitant, et si c'est le cas, le faire en parallèle par fichier rendra l'opération plus lente , pas plus rapide, car vous forcerez le disque à rechercher constamment d'avant en arrière entre les fichiers.
Joel Coehoorn

Bien que le zip ne soit pas une bonne idée (l'exécution de la compression algo sur des milliers de fichiers peut prendre un certain temps), tar peut être viable.
Rob

@JoelCoehoorn toujours, il y a des cas où ce n'est pas le cas: par exemple plusieurs broches + petits fichiers (ou simplement des lectures aléatoires). Dans ce scénario, "cp parallèle" serait utile.
CAFxX

Réponses:


8

Tant que vous limitez les commandes de copie que vous exécutez, vous pouvez probablement utiliser un script comme celui publié par 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
Attention cependant: ce script rompt avec les noms de fichiers contenant des espaces ou des caractères globulaires.
slhck

@OldWolf - Pouvez-vous expliquer comment ce script fonctionne? Par exemple, quelle partie fait la parallélisation?
dsg

3
@dsg: &la fin de la cpcommande permet à la whileboucle de continuer et de démarrer la prochaine commande cp sans attendre. La xargscommande transmet les noms de fichiers par groupes de 4 (MAX_PARALLEL) à la whileboucle.
RedGrittyBrick

Ça ne marche pas pour moi. Je ne suis pas sûr qu'il soit possible d'accélérer cp. Vous pouvez évidemment accélérer le calcul grâce au multithreading. Mais je ne pense pas qu'il en soit de même pour l'adaptation des données du disque dur.
Adobe

9

Si vous avez GNU Parallel http://www.gnu.org/software/parallel/ installé, vous pouvez le faire:

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

Vous pouvez installer GNU Parallel simplement en:

$ (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

Regardez les vidéos d'introduction pour GNU Parallel pour en savoir plus: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1


3

Une façon serait d'utiliser rsync qui ne copiera que les modifications - les nouveaux fichiers et les parties modifiées des autres fichiers.

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

L'exécution de toute forme d'opération de copie parallèle inondera probablement votre réseau et l'opération de copie s'arrêtera ou souffrira de goulots d'étranglement sur le disque source ou de destination.


2

Honnêtement, le meilleur outil est le gsutil de Google. Il gère les copies parallèles avec récursion de répertoire. La plupart des autres méthodes que j'ai vues ne peuvent pas gérer la récursivité des répertoires. Ils ne mentionnent pas spécifiquement le système de fichiers local aux copies du système de fichiers local dans leurs documents, mais cela fonctionne comme un charme.

C'est un autre binaire à installer, mais probablement un que vous pourriez déjà exécuter compte tenu de l'ensemble de l'adoption du service cloud de nos jours.


2

Rsync parallèle utilisant 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/{//}/'

sur un réseau local d'entreprise, rsync unique fait environ 800 Mbps; avec 6-8 emplois, je peux obtenir plus de 2,5 Gbps (au détriment d'une charge élevée). Limité par les disques.


0

Il y a beaucoup de choses à considérer selon la topologie dont vous disposez. Mais avant de commencer à penser à des solutions complexes, vous pouvez simplement essayer de diviser la tâche en deux tâches et vérifier si le temps nécessaire sera considérablement réduit:

La prochaine fois, essayez:

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

(vous voudrez peut-être remplacer [al] * par quelque chose d'autre qui correspond à environ la moitié des fichiers - peut-être [0-4] * - selon le contenu du dossier)

Si le temps ne s'améliore pas de façon spectaculaire, il peut être plus important de vérifier s'il est nécessaire de copier tous les fichiers (quel est le rapport des fichiers modifiés sur tous les fichiers?)

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.