Compressez rapidement un grand nombre de fichiers volumineux

16

J'ai environ 200 Go de données de journal générées quotidiennement, réparties sur environ 150 fichiers journaux différents.

J'ai un script qui déplace les fichiers vers un emplacement temporaire et fait un tar-bz2 sur le répertoire temporaire.

J'obtiens de bons résultats car les journaux de 200 Go sont compressés à environ 12-15 Go.

Le problème est qu'il faut une éternité pour compresser les fichiers. La tâche cron s'exécute tous les jours à 2 h 30 et continue jusqu'à 17 h 00-18 h 00.

Existe-t-il un moyen d'améliorer la vitesse de compression et de terminer le travail plus rapidement? Des idées?

Ne vous inquiétez pas des autres processus et de tout, l'emplacement où la compression se produit est sur un NAS , et je peux exécuter monter le NAS sur une machine virtuelle dédiée et exécuter le script de compression à partir de là.

Voici la sortie de top pour référence:

top - 15:53:50 up 1093 days,  6:36,  1 user,  load average: 1.00, 1.05, 1.07
Tasks: 101 total,   3 running,  98 sleeping,   0 stopped,   0 zombie
Cpu(s): 25.1%us,  0.7%sy,  0.0%ni, 74.1%id,  0.0%wa,  0.0%hi,  0.1%si,  0.1%st
Mem:   8388608k total,  8334844k used,    53764k free,     9800k buffers
Swap: 12550136k total,      488k used, 12549648k free,  4936168k cached
 PID  USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 7086 appmon    18   0 13256 7880  440 R 96.7  0.1 791:16.83 bzip2
7085  appmon    18   0 19452 1148  856 S  0.0  0.0   1:45.41 tar cjvf /nwk_storelogs/compressed_logs/compressed_logs_2016_30_04.tar.bz2 /nwk_storelogs/temp/ASPEN-GC-32459:nkp-aspn-1014.log /nwk_stor
30756 appmon    15   0 85952 1944 1000 S  0.0  0.0   0:00.00 sshd: appmon@pts/0
30757 appmon    15   0 64884 1816 1032 S  0.0  0.0   0:00.01 -tcsh
anu
la source
2
Si vous avez plusieurs processeurs et que vous avez ou pouvez le diviser en plusieurs fichiers tar, vous pouvez exécuter plusieurs compressions.
Jeff Schaller
@JeffSchaller serait-il possible que plusieurs processus bzip2 compressent différents fichiers mais écrivent dans le même tar.bz2fichier?
Anu
2
Les fichiers journaux sont-ils générés sur le disque local avant de passer au NAS? Si tel est le cas, alors déplacez-vous; de cette façon, vous n'envoyez que 15 Go de données sur le réseau plutôt que 100 (déplacement) puis 115 (100 lecture + 15 écriture) lors de la compression. Alternativement, il semble que vous puissiez être lié au processeur sur ce processus bzip2, donc exécuter plusieurs en parallèle (un par processeur) peut aider (jusqu'à ce que vous atteigniez la limite d'E / S). Ou utilisez une compression plus simple (par exemple "gzip -1"). Il n'économisera pas autant d'espace disque mais il s'exécutera plus rapidement.
Stephen Harris
@Sukminder Je vais certainement essayer cela et voir la différence de taille. Merci.
Anu
Votre topsortie montre que votre bzip2processus à un seul thread utilise un cœur au maximum, mais que vous l'exécutez sur un système à quatre cœurs (un processus utilisant 100% CPU -> 25.1%temps CPU de l'espace utilisateur, 74% inactif). Ainsi, avec des modifications mineures, vous pouvez aller 4 fois plus vite, à moins que quelque chose d'autre ne devienne le goulot d'étranglement. Lisez attentivement la réponse de Gilles. Pensez à utiliser le CPU dans la même case que les disques contenant les données pour effectuer la compression. (Vous pouvez même compresser certains de vos fichiers sur une boîte, d'autres sur l'autre et les archiver ensuite, de sorte que les deux processeurs sont utilisés.)
Peter Cordes

Réponses:

25

La première étape consiste à déterminer quel est le goulot d'étranglement: s'agit-il d'E / S disque, d'E / S réseau ou de CPU?

Si le goulot d'étranglement est l'E / S du disque, vous ne pouvez pas faire grand-chose. Assurez-vous que les disques ne servent pas de nombreuses demandes parallèles car cela ne peut que diminuer les performances.

Si le goulot d'étranglement est l'E / S réseau, exécutez le processus de compression sur la machine où les fichiers sont stockés: l'exécuter sur une machine avec un processeur plus puissant n'aide que si le processeur est le goulot d'étranglement.

Si le goulot d'étranglement est le CPU, la première chose à considérer est d'utiliser un algorithme de compression plus rapide. Bzip2 n'est pas nécessairement un mauvais choix - sa principale faiblesse est la vitesse de décompression - mais vous pouvez utiliser gzip et sacrifier une certaine taille pour la vitesse de compression, ou essayer d'autres formats tels que lzop ou lzma. Vous pouvez également régler le niveau de compression: par défaut, bzip2 -9(taille de bloc maximale, donc compression maximale, mais aussi temps de compression le plus long); définissez la variable d'environnement BZIP2sur une valeur comme -3pour essayer le niveau de compression 3. Ce thread et ce thread discutent des algorithmes de compression courants; en particulier, ce billet de blog cité par derobert donne quelques repères qui suggèrent que gzip -9oubzip2avec un faible niveau pourrait être un bon compromis par rapport à bzip2 -9. Cet autre benchmark qui inclut également lzma (l'algorithme de 7zip, vous pouvez donc l'utiliser à la 7zplace de tar --lzma) suggère qu'à lzmaun faible niveau, le taux de compression bzip2 peut être atteint plus rapidement. N'importe quel choix autre que bzip2 améliorera le temps de décompression. Gardez à l'esprit que le taux de compression dépend des données et que la vitesse de compression dépend de la version du programme de compression, de la façon dont il a été compilé et du processeur sur lequel il est exécuté.

Une autre option si le goulot d'étranglement est le CPU et que vous avez plusieurs cœurs est de paralléliser la compression. Il y a deux façons de procéder. Celui qui fonctionne avec n'importe quel algorithme de compression consiste à compresser les fichiers séparément (individuellement ou en quelques groupes) et à utiliser parallelpour exécuter les commandes d'archivage / compression en parallèle. Cela peut réduire le taux de compression mais augmente la vitesse de récupération d'un fichier individuel et fonctionne avec n'importe quel outil. L'autre approche consiste à utiliser une implémentation parallèle de l'outil de compression; ce fil en énumère plusieurs.

Gilles 'SO- arrête d'être méchant'
la source
4
"Si le goulot d'étranglement est l'E / S du disque, vous ne pouvez pas faire grand-chose." C'est probablement vrai ici, car le taux de compression est déjà bon, mais en général, lorsque les E / S sont le goulot d'étranglement, il peut être utile d'envisager d'utiliser plus de CPU pour obtenir un meilleur taux de compression (en utilisant différents paramètres de compression ou un algorithme différent). .. vous ne pouvez pas vraiment réduire le "je" (car vous devez lire toutes les données) mais vous pouvez parfois réduire considérablement le "o" :-)
psmears
1
Si vous dites de 7zne pas créer une archive "solide" ou de limiter la taille des blocs "solides", il exécutera plusieurs threads LZMA en parallèle, IIRC. Les données des fichiers journaux sont un cas particulier pour la compression, car elles ont tendance à être très redondantes (beaucoup de similitudes entre les lignes). Cela vaut vraiment la peine de tester gzip, bzip2et xzsur les fichiers journaux spécifiques de l'OP, plutôt que de simplement regarder des repères de compression génériques pour exclure toutes les options. Compresseurs Même rapides sont à considérer ( lzop, lz4, snappy).
Peter Cordes
Le compresseur LZMA préféré de nos jours est xz. Utilisez tar -Jou --xzpas --lzma. .lzmaest considéré comme un format de fichier "hérité" . Les multiples itérations des formats de fichiers pour la compression LZMA sont un peu gênants, et quelque chose qu'ils auraient dû bien faire la première fois. Mais AFAIK est fondamentalement bon maintenant, et .xz n'est pas sur le point d'être remplacé par un autre format de fichier pour le même flux de compression.
Peter Cordes
7z a une excellente compression et multi-threading, mais à cause du format d'archive (a besoin d'un index, ou peut-être de bugs?) Je ne pense pas qu'il puisse être utilisé au milieu d'un pipeline - il n'utilisera pas stdin et stdout en même temps
Xen2050
C'était vraiment utile et perspicace. Mon équipe a pensé que l'opération sur NFS était un gros goulot d'étranglement.
Anu
16

Vous pouvez installer pigz, gzip parallèle et utiliser tar avec la compression multi-thread. Comme:

tar -I pigz -cf file.tar.gz *

Où l' -Ioption est:

-I, --use-compress-program PROG
  filter through PROG

Bien sûr, si votre NAS n'a pas plusieurs cœurs / CPU puissant, vous êtes de toute façon limité par la puissance du CPU.

La vitesse du disque dur / de la baie sur laquelle la machine virtuelle et la compression s'exécutent peut également être un goulot d'étranglement.

labyrinthes
la source
1
Et si vous souhaitez utiliser bzip2, vous pouvez utiliser pbzip2ou lbzip2.
Radovan Garabík
2
Ceci est votre meilleure réponse. Mais d'abord, assurez-vous que votre premier déplacement se fait vers un emplacement qui se trouve sur le même système de fichiers que les fichiers d'origine. Sinon, votre "déplacement" est vraiment une copie d'octets puis une suppression. Sur le même système de fichiers, un déplacement est un réarrangement des liens du système de fichiers. C'est des ordres de grandeur plus rapides. Pour mes fichiers journaux de centaines de gigaoctets, pigz a fait toute la différence. Vous pouvez lui indiquer le nombre de threads parallèles à exécuter. Tant que votre processeur a plusieurs cœurs, je ne passerais pas beaucoup de temps à enquêter. Vous voudrez probablement pigz dans tous les cas; vous pouvez obtenir votre accélération immédiatement.
Mike S
Une fois que vous avez pigé, regardez vos sorties htop et iostat et observez les performances de votre système, si vous souhaitez approfondir votre système. Mais encore une fois, je n'essaierai plus de compresser de gros fichiers sans pigz. Sur un système multicœur moderne, il est stupide de ne pas l'utiliser. C'est une telle victoire immédiate - vous verrez.
Mike S
7

De loin, le moyen le plus rapide et le plus efficace de compresser des données est d'en générer moins.

Quels types de journaux générez-vous? 200 Go par jour, ça fait beaucoup (sauf si vous êtes Google ou un FAI ...), considérez que 1 Mo de texte équivaut à environ 500 pages, donc vous générez l'équivalent de 100 millions de pages de texte par jour, vous aurez remplir la bibliothèque du congrès dans une semaine.

Consultez vos données de journal si vous pouvez les réduire d'une manière ou d'une autre et obtenez toujours ce dont vous avez besoin à partir des journaux. Par exemple, en baissant le niveau de journal ou en utilisant un format de journal terser. Ou si vous utilisez les journaux pour les statistiques, traitez les statistiques à la volée et videz un fichier avec le résumé, puis filtrez les journaux avant la compression pour le stockage.

Emily L.
la source
1
Il s'agit d'une solution philosophique intéressante. La solution de la plupart des problèmes de vie est d'éviter d'avoir le problème tout à fait n'est-ce pas. C'est jusqu'à ce que l'on examine de près la suggestion et se rend compte qu'il y a des centaines de personnes et des milliers d'approbations que l'on doit passer pour y parvenir.
Anu
1
@anu Aucun contexte n'a été donné à la question, je n'en ai donc pas supposé. Et pourriez-vous s'il vous plaît me dire d'où vous avez obtenu le nombre de milliers d'approbations? Pour moi, il semble que vous ayez inventé ça.
Emily L.
Je vote positivement. Il s'agit de la solution la plus souvent négligée, mais une fois remarquée, à de nombreux problèmes de la vie.
jrw32982 prend en charge Monica
1
Eh bien ... maintenant que je ne travaille plus là-bas, je peux au moins révéler que c'était un problème chez Apple. Plus précisément sur la pile de services qui dessert l'App Store en ligne ... alors oui, des milliers d'approbations sont à peu près une réalité car ils ont des milliers de microservices et chacun d'eux produit des journaux qui doivent être compressés et devront approuver la modification de leur niveaux de journalisation etc ... Quoi qu'il en soit ... nous avons trouvé une solution pour ce btw interne .. qui est à peu près équivalent à gzip parallèle qui est déchargé vers un autre microservices.
anu
3

Vous pouvez réduire la quantité de compression (en termes d'espace économisé) pour la rendre plus rapide. Pour commencer, bzip2 est BEAUCOUP plus lent que gzip, bien qu'il se comprime plus petit. Vous pouvez également modifier le niveau de compression de bzip2, gzip ou de la plupart des programmes de compression pour échanger la taille contre la vitesse.

Si vous n'êtes pas disposé à échanger la taille de la vitesse, vous pouvez toujours obtenir la même taille ou plus petite tout en obtenant une amélioration de la vitesse en utilisant un compresseur qui utilise LZMA (xz par exemple).

Vous trouverez des repères si vous recherchez, mais votre meilleur pari est de faire des tests avec votre propre fichier sur votre matériel cible.

EricS
la source
3

Si la seule exigence est que la compression soit rapide , je recommanderais très fortement lz4 .

Il est utilisé dans de nombreux endroits où la vitesse de compression est plus importante que le taux de compression (par exemple, les systèmes de fichiers avec compression transparente comme ZFS)

pdo
la source
Je n'en ai jamais entendu parler auparavant, y a-t-il un programme probablement déjà installé pratiquement partout qui l'utilise, comme xz?
Xen2050