2010-12-03 7 views
34

J'ai un ensemble de serveurs remplis chacun d'un tas de fichiers qui peuvent être gzippés. Les serveurs ont tous un nombre différent de cœurs. Comment puis-je écrire un script bash pour lancer un gzip pour chaque core et m'assurer que les gzips ne compressent pas le même fichier?Gzip avec tous les cœurs

+0

Etes-vous sûr que la vitesse du disque dur ne les limitera pas? – ruslik

+1

@rulik, exactement, la vitesse du disque dur sera le goulot d'étranglement ou gzip aurait ajouté un support multi-processeur il y a longtemps. –

+9

Je ne suis pas d'accord. Exécuter gzip sur une série de fichiers dans mon expérience pèse le CPU à 100%, les E/S disque reste faible. Oui, dans un cas très extrême, vous pourriez voir les E/S du disque devenir le prochain goulot d'étranglement, mais c'est une excellente raison d'utiliser ces noyaux supplémentaires au lieu d'exécuter un seul thread. – Demosthenex

Répondre

51

Si vous utilisez Linux, vous pouvez utiliser xargs de GNU pour lancer autant de processus que vous avez de cœurs.

CORES=$(grep -c '^processor' /proc/cpuinfo) 
find /source -type f -print0 | xargs -0 -n 1 -P $CORES gzip -9 
  • trouver -print0/xargs -0 vous protège contre les espaces dans les noms de fichiers
  • xargs -n 1 signifie un processus gzip par fichier
  • xargs -P spécifie le nombre d'emplois
  • gzip -9 signifie compression maximale
+8

Il n'est pas nécessaire d'exporter la variable. Vous devriez utiliser '$()' au lieu de backticks. Il n'est pas nécessaire d'utiliser 'cat' -' grep' accepte un fichier comme argument. GNU 'grep' (si pas d'autres aussi) peut compter, donc vous n'avez pas besoin de' wc'. Résultat final: 'CORES = $ (grep -c^processeur/proc/cpuinfo)' –

+1

Vous avez absolument raison. J'étais paresseux en train de la chercher et je l'ai laissé bricolé. C'est beaucoup plus propre. – Demosthenex

+0

Si vous voulez réserver disons 2 processeurs pour d'autres programmes, vous pouvez utiliser ce qui suit (il y a probablement un moyen plus propre ou plus bash de le faire): CORES = $ (grep -c '^ processor'/proc/cpuinfo | perl -ane 'print $ F [0] - 2') – Morlock

6

Vous voudrez peut-être envisager de vérifier GNU parallel. J'ai aussi trouvé ce video on youtube qui semble faire ce que vous cherchez.

+0

Mention parallèle qu'il utilise des indicateurs similaires à xargs, ironiquement, j'ai découvert récemment que xargs inclut maintenant la possibilité de lancer plusieurs processus, voir ma réponse. – Demosthenex

54

Il existe une implémentation de gzip multithread, pigz. Comme il est en train de compresser un fichier sur plusieurs threads, il devrait être capable de lire sur le disque plus efficacement, comparé à la compression de plusieurs fichiers à la fois.

+1

Je pense que c'est une solution supérieure! Si chaque bloc à compresser s'exécute dans des threads séparés, il est préférable d'utiliser quelque chose comme xargs pour lancer un processus par fichier! D'un autre côté, si vous ne pouvez pas installer un logiciel personnalisé sur des serveurs $ X, vous pouvez revenir au comportement de xargs. Super trouvaille! – Demosthenex

+2

C'est génial à savoir. Malheureusement, pigz n'est pas sur nos serveurs. :( – User1

+0

Note: pigz ne peut faire qu'une compression parallèle, pas une décompression (plus d'une limitation de la compression gz que pigz si je comprends bien.) Lorsque la décompression utilise encore 4 threads, séparer la lecture, l'écriture et la vérification. – qwertzguy