Il est temps de compresser de très gros fichiers (100G)

27

Je me retrouve à devoir compresser un certain nombre de fichiers très volumineux (80 Go) et je suis surpris de la (manque de) vitesse de mon système. J'obtiens une vitesse de conversion d'environ 500 Mo / min; en utilisant top, je semble utiliser un seul processeur à environ 100%.

Je suis sûr que ce n'est pas (seulement) la vitesse d'accès au disque, car la création d'un tarfichier (c'est ainsi que le fichier 80G a été créé) n'a pris que quelques minutes (peut-être 5 ou 10), mais après plus de 2 heures, ma simple commande gzip est toujours pas fini.

En résumé:

tar -cvf myStuff.tar myDir/*

Il a fallu moins de 5 minutes pour créer un fichier tar 87 G

gzip myStuff.tar

A pris deux heures et 10 minutes, créant un fichier zip 55G.

Ma question: est-ce normal? Existe-t-il certaines options gzippour accélérer les choses? Serait-il plus rapide de concaténer les commandes et de les utiliser tar -cvfz? J'ai vu une référence à pigz- Mise en œuvre parallèle de GZip - mais malheureusement je ne peux pas installer de logiciel sur la machine que j'utilise, donc ce n'est pas une option pour moi. Voir par exemple cette question précédente .

J'ai l'intention d'essayer certaines de ces options moi-même et de les chronométrer - mais il est fort probable que je ne frapperai pas "la combinaison magique" des options. J'espère que quelqu'un sur ce site connaît la bonne astuce pour accélérer les choses.

Lorsque je disposerai des résultats d'autres essais, je mettrai à jour cette question - mais si quelqu'un a une astuce particulièrement intéressante, je l'apprécierais vraiment. Peut-être que le gzip prend juste plus de temps de traitement que je ne le pensais ...

MISE À JOUR

Comme promis, j'ai essayé les astuces suggérées ci-dessous: changer la quantité de compression et changer la destination du fichier. J'ai obtenu les résultats suivants pour un goudron d'environ 4,1 Go:

flag    user      system   size    sameDisk
-1     189.77s    13.64s  2.786G     +7.2s 
-2     197.20s    12.88s  2.776G     +3.4s
-3     207.03s    10.49s  2.739G     +1.2s
-4     223.28s    13.73s  2.735G     +0.9s
-5     237.79s     9.28s  2.704G     -0.4s
-6     271.69s    14.56s  2.700G     +1.4s
-7     307.70s    10.97s  2.699G     +0.9s
-8     528.66s    10.51s  2.698G     -6.3s
-9     722.61s    12.24s  2.698G     -4.0s

Alors oui, changer le drapeau par défaut -6en le plus rapide -1me donne une accélération de 30%, avec (pour mes données) pratiquement aucune modification de la taille du fichier zip. Que j'utilise le même disque ou un autre ne fait pratiquement aucune différence (je devrais l'exécuter plusieurs fois pour obtenir une signification statistique).

Si quelqu'un est intéressé, j'ai généré ces repères de synchronisation en utilisant les deux scripts suivants:

#!/bin/bash
# compare compression speeds with different options
sameDisk='./'
otherDisk='/tmp/'
sourceDir='/dirToCompress'
logFile='./timerOutput'
rm $logFile

for i in {1..9}
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $sameDisk $logFile
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $otherDisk $logFile
done

Et le deuxième script ( compressWith):

#!/bin/bash
# use: compressWith sourceDir compressionFlag destinationDisk logFile
echo "compressing $1 to $3 with setting $2" >> $4
tar -c $1 | gzip -$2 > $3test-$2.tar.gz

Trois choses à noter:

  1. Utiliser /usr/bin/timeplutôt que time, car la commande intégrée de bashcomporte beaucoup moins d'options que la commande GNU
  2. Je n'ai pas pris la peine d'utiliser l' --formatoption bien que cela rendrait le fichier journal plus facile à lire
  3. J'ai utilisé un script dans un script car il timesemblait ne fonctionner que sur la première commande d'une séquence piped (donc je l'ai fait ressembler à une seule commande ...).

Avec tout cela appris, mes conclusions sont

  1. Accélérez les choses avec le -1drapeau (réponse acceptée)
  2. Beaucoup plus de temps est consacré à la compression des données qu'à la lecture à partir du disque
  3. Investissez dans un logiciel de compression plus rapide ( pigzsemble être un bon choix).
  4. Si vous avez plusieurs fichiers à compresser, vous pouvez mettre chaque gzipcommande dans son propre thread et utiliser plus de CPU disponible (pauvre pigz)

Merci à tous ceux qui m'ont aidé à apprendre tout cela!

Floris
la source
tar -cvf ne fait aucune compression donc ce sera plus rapide
parkydr
2
@Floris: quel type de données essayez-vous de compresser? side-note: $> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gzvous montrera à quelle vitesse votre machine compresse les trucs. side-note2: stocker le résultat sur un disque différent.
Akira
3
Désolé, j'ai mal lu votre question. gzip a l'option --fast pour sélectionner la compression la plus rapide
parkydr
1
@parkydr: L'option --fast est une option que je ne connaissais pas ... c'est la toute dernière de la manpage, et je n'ai pas lu jusqu'ici (car elle est triée par 'commande à lettre unique', qui est -#) . Cela m'apprendra à RTFM! Ce sera la prochaine chose que j'essaierai!
Floris
2
Notez que si un compilateur approprié est disponible sur la machine et que les autorisations du système de fichiers ne sont pas définies pour interdire l'exécution des binaires à partir des répertoires auxquels vous avez accès, vous pouvez le compiler pigzet l'exécuter à partir de l'endroit où vous l'avez construit, sans l'installer. S'il n'y a pas de compilateur, vous pouvez le compiler de manière croisée sur un autre ordinateur, bien que cela commence à faire plus d'efforts que cela ne vaut la peine. (Je suppose que cela dépend à quel point vous avez besoin de cette compression pour fonctionner plus rapidement.)
David Z

Réponses:

27

Vous pouvez modifier la vitesse de gzip en utilisant --fast --bestou -#où # est un nombre compris entre 1 et 9 (1 est la compression la plus rapide mais la moins, 9 est la compression la plus lente mais la plus). Par défaut, gzip s'exécute au niveau 6.

robingrindrod
la source
26

La raison pour laquelle tar prend si peu de temps par rapport à gzip est qu'il y a très peu de temps de calcul pour copier vos fichiers dans un seul fichier (c'est ce qu'il fait). gzip d'autre part, utilise en fait des algorithmes de compression pour réduire le fichier tar.

Le problème est que gzip est contraint (comme vous l'avez découvert) à un seul thread.

Entrez pigz , qui peut utiliser plusieurs threads pour effectuer la compression. Voici un exemple d'utilisation:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip

Il y a un joli résumé succint de l'option --use-compress-program sur un site frère .

Steve Gore
la source
Merci pour votre réponse et vos liens. J'ai en fait mentionné pigz dans la question.
Floris
C'est la bonne réponse ici ..!
stolsvik
4

Il semble que j'utilise un seul processeur à environ 100%.

Cela implique qu'il n'y a pas de problème de performances d'E / S mais que la compression n'utilise qu'un seul thread (ce qui sera le cas avec gzip).

Si vous parvenez à obtenir l'accès / l'accord nécessaire pour installer d'autres outils, 7zip prend également en charge plusieurs threads pour tirer parti des processeurs multicœurs, bien que je ne sois pas sûr que cela s'étende au format gzip ainsi qu'au sien.

Si vous êtes limité à l'utilisation de gzip pour le moment et que vous avez plusieurs fichiers à compresser, vous pouvez essayer de les compresser individuellement - de cette façon, vous utiliserez plus de ce processeur multicœur en exécutant plus d'un processus en parallèle. Attention toutefois à ne pas en faire trop, car dès que vous atteindrez la capacité de votre sous-système d'E / S, les performances chuteront brusquement (à un niveau inférieur à si vous utilisiez un processus / thread) car la latence des mouvements de la tête devient significative. goulot.

David Spillett
la source
Merci pour votre contribution. Vous m'avez donné une idée (pour laquelle vous obtenez un vote positif): comme j'ai plusieurs archives à créer, je peux simplement écrire les commandes individuelles suivies d'un &- puis laisser le système s'en occuper à partir de là. Chacun fonctionnera sur son propre processeur, et comme je passe beaucoup plus de temps sur la compression que sur les E / S, il faudra autant de temps pour en faire un que pour les 10. J'obtiens donc des "performances multi-cœurs" à partir d'un exécutable à thread unique ...
Floris
1

On peut également exploiter le nombre de processus disponibles dans pigz, ce qui est généralement plus rapide comme le montre la commande suivante

tar cf - répertoire à archiver | pigz -0 -p largenumber> mydir.tar.gz

Exemple - tar cf - patha | pigz -0 -p 32> patha.tar.gz

C'est probablement plus rapide que les méthodes suggérées dans le post car -p est le nombre de processus que l'on peut exécuter. D'après mon expérience personnelle, la définition d'une valeur très élevée ne nuit pas aux performances si le répertoire à archiver se compose d'un grand nombre de petits fichiers. Sinon, la valeur par défaut considérée est 8. Pour les fichiers volumineux, ma recommandation serait de définir cette valeur comme le nombre total de threads pris en charge sur le système.

Un exemple de définition d'une valeur de p = 32 dans le cas d'une machine à 32 CPU aide.

0 est destiné à la compression pigz la plus rapide car il ne comprime pas l'archive et se concentre plutôt sur la vitesse. La valeur par défaut est 6 pour la compression.

Ankit Shah
la source