64 votes

Une meilleure recherche unix avec un traitement parallèle ?

Le programme utilitaire unix find(1) est très utile car il me permet d'effectuer une action sur de nombreux fichiers qui correspondent à certaines spécifications, par exemple.

find /dump -type f -name '*.xml' -exec java -jar ProcessFile.jar {} \;

Le code ci-dessus pourrait exécuter un script ou un outil sur chaque fichier XML dans un répertoire particulier.

Disons que mon script/programme prend beaucoup de temps CPU et que j'ai 8 processeurs. Ce serait bien de traiter jusqu'à 8 fichiers à la fois.

GNU make permet le traitement de tâches parallèles avec le drapeau -j mais find ne semble pas avoir une telle fonctionnalité. Existe-t-il une méthode alternative générique de planification de tâches pour aborder cela?

80voto

ulidtko Points 2796

xargs avec l'option -P (nombre de processus). Disons que je voulais compresser tous les fichiers journaux dans un répertoire sur une machine à 4 CPU :

find . -name '*.log' -mtime +3 -print0 | xargs -0 -P 4 bzip2

Vous pouvez également dire -n pour le nombre maximum d'unités de travail par processus. Donc, disons que j'avais 2500 fichiers et que j'ai dit :

find . -name '*.log' -mtime +3 -print0 | xargs -0 -n 500 -P 4 bzip2

Cela démarrerait 4 processus bzip2, chacun avec 500 fichiers, et puis quand le premier aurait fini, un autre serait démarré pour les derniers 500 fichiers.

Je ne suis pas sûr pourquoi la réponse précédente utilise à la fois xargs et make, vous avez là deux moteurs parallèles!

11 votes

Avec find/xargs, faites attention : find utilise par défaut des sauts de ligne comme délimiteurs de sortie, mais xargs utilise par défaut n'importe quel espace blanc comme délimiteur d'entrée. Utilisez -0 sur les deux pour plus de sécurité, ou passez à GNU parallel qui utilise par défaut des sauts de ligne comme délimiteurs d'entrée (en correspondance avec la sortie de find).

1 votes

Wow, incroyable! Je viens de vérifier, et c'est vrai, xargs a une option -P!

2 votes

Faites attention à l'utilisation de xargs -P - il a un bug jamais corrigé qui altère la sortie (contrairement à parallel) chaque fois que 2 threads produisent une sortie exactement au même moment...

53voto

shabunc Points 606

GNU parallel peut également aider.

find /dump -type f -name '*.xml' | parallel -j8 java -jar ProcessFile.jar {}

Notez que sans l'argument -j8, parallel utilise par défaut le nombre de cœurs de votre machine :-)

7voto

Joey deVilla Points 4487

Il n'est pas nécessaire de "corriger" find - utilisez plutôt make lui-même pour gérer le parallélisme.

Faites en sorte que votre processus crée un fichier journal ou tout autre fichier de sortie, puis utilisez un fichier Makefile comme celui-ci :

.SUFFIXES:  .xml .out

.xml.out:
        java -jar ProcessFile.jar $< 1> $@

et appelez-le ainsi :

find /dump -type f -name '*.xml' | sed -e 's/\.xml$/.out/' | xargs make -j8

Mieux encore, si vous vous assurez que le fichier de sortie n'est créé qu'à la fin réussie du processus Java, vous pouvez tirer profit de la gestion des dépendances de make pour vous assurer que seuls les fichiers non traités sont gérés la prochaine fois.

2 votes

J'espère qu'il n'y a pas d'espaces ou d'autres caractères "intéressants" dans ces noms de fichiers; Make ne gère pas cela très élégamment.

0 votes

Excellente idée! Je n'ai jamais pensé à utiliser des makefiles de cette façon.

5voto

Mark Evans Points 49

Find a une option parallèle que vous pouvez utiliser directement en utilisant le symbole "+"; aucun xargs n'est nécessaire. En le combinant avec grep, il peut parcourir rapidement votre arborescence à la recherche de correspondances. Par exemple, si je cherche tous les fichiers de mon répertoire sources contenant la chaîne 'foo', je peux invoquer

find sources -type f -exec grep -H foo {} +

23 votes

En lisant le manuel de recherche, vous pouvez voir que la syntaxe -exec command + ne s'exécute pas en parallèle, mais "groupe" de nombreux fichiers ensemble et exécute la commande avec plusieurs fichiers comme arguments en même temps. Il arrive que grep puisse parcourir ses cibles en parallèle.

3voto

Paul Points 1

Toutes les suggestions font fonctionner l'exécution en parallèle, mais si votre arborescence de fichiers est suffisamment grande, le goulot d'étranglement peut se trouver dans la recherche elle-même. Un de mes collègues a écrit locar comme une recherche parallèle qui est très utile lorsque votre système de fichiers peut effectuer des analyses en parallèle. Cela peut ne pas aider si votre système de fichiers est sur un seul disque dur, mais s'il s'agit d'un périphérique RAID, d'un SSD ou encore mieux d'un système de fichiers distribué, cela aidera énormément.

locar effectuera l'analyse des fichiers en parallèle sur plusieurs répertoires, vous obtiendrez donc la liste des fichiers plus rapidement et pourrez ensuite également la combiner avec xargs ou parallel pour exécuter des tâches en parallèle également.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X