bzip2 trop lent. Plusieurs cœurs sont disponibles

31

J'exécute cette commande:

pg_dumpall | bzip2 > cluster-$(date --iso).sql.bz2

Cela prend trop de temps. Je regarde les processus avec top. Le processus bzip2 prend environ 95% et postgres 5% d'un cœur. L' waentrée est faible. Cela signifie que le disque n'est pas le goulot d'étranglement.

Que puis-je faire pour augmenter les performances?

Laissez peut-être bzip2 utiliser plus de cœurs. Les serveurs ont 16 cœurs.

Ou utiliser une alternative à bzip2?

Que puis-je faire pour augmenter les performances?

Guettli
la source
8
Sauf si vous avez besoin de bzip2 pour des raisons héritées, mon expérience personnelle a montré que xz donne une meilleure compression / durée que bzip2. Il est également enfilé si vous obtenez un nouveau programme suffisant, et il vous permet de faire évoluer le temps et l'utilisation de la mémoire de gzipish à massif en fonction de ce que vous voulez.
Perkins
6
"pigz" est une autre option - il produit une sortie gzip plutôt qu'une sortie bzip2. Et fondamentalement, tout comprend gzip.
Criggie
Vous pouvez essayer de le chiffrer symétriquement avec GnuPG avec la compression bzip2; il semble étonnamment rapide par rapport à la compression, pour une raison inconnue, même avec le niveau de compression le plus élevé. Il est possible que l'algorithme soit plus rapide que l'efficacité de mon programme de compression habituel, basé sur une interface graphique.
Shule
2
Vous n'avez pas précisé les exigences de votre algorithme alternatif. Bzip2 est séparable. Est-ce important pour toi?
Martin Smith
7
" Que puis-je faire pour augmenter les performances? " - ne pas les compresser? Vous ne dites pas en fait que vous en avez besoin compressé, et ne pas faire le travail est toujours plus rapide que faire le travail. Faites du disque le goulot d'étranglement.
TessellatingHeckler

Réponses:

49

Il existe de nombreux algorithmes de compression et l' bzip2un des plus lents. Plain gziptend à être significativement plus rapide, à une compression généralement pas bien pire. Quand la vitesse est la plus importante, lzopc'est ma préférée. Mauvaise compression, mais oh si vite.

J'ai décidé de m'amuser et de comparer quelques algorithmes, y compris leurs implémentations parallèles. Le fichier d'entrée est la sortie de la pg_dumpallcommande sur mon poste de travail, un fichier SQL de 1913 Mo. Le matériel est un ancien i5 quadricœur. Les heures sont des heures d'horloge murale de la compression uniquement. Les implémentations parallèles sont définies pour utiliser les 4 cœurs. Tableau trié par vitesse de compression.

Algorithm     Compressed size        Compression          Decompression

lzop           398MB    20.8%      4.2s    455.6MB/s     3.1s    617.3MB/s
lz4            416MB    21.7%      4.5s    424.2MB/s     1.6s   1181.3MB/s
brotli (q0)    307MB    16.1%      7.3s    262.1MB/s     4.9s    390.5MB/s
brotli (q1)    234MB    12.2%      8.7s    220.0MB/s     4.9s    390.5MB/s
zstd           266MB    13.9%     11.9s    161.1MB/s     3.5s    539.5MB/s
pigz (x4)      232MB    12.1%     13.1s    146.1MB/s     4.2s    455.6MB/s
gzip           232MB    12.1%     39.1s     48.9MB/s     9.2s    208.0MB/s
lbzip2 (x4)    188MB     9.9%     42.0s     45.6MB/s    13.2s    144.9MB/s
pbzip2 (x4)    189MB     9.9%    117.5s     16.3MB/s    20.1s     95.2MB/s
bzip2          189MB     9.9%    273.4s      7.0MB/s    42.8s     44.7MB/s
pixz (x4)      132MB     6.9%    456.3s      4.2MB/s     7.9s    242.2MB/s
xz             132MB     6.9%   1027.8s      1.9MB/s    17.3s    110.6MB/s
brotli (q11)   141MB     7.4%   4979.2s      0.4MB/s     3.6s    531.6MB/s

Si les 16 cœurs de votre serveur sont suffisamment inactifs pour que tous puissent être utilisés pour la compression, pbzip2cela vous donnera probablement une accélération très importante. Mais vous avez encore besoin de plus de vitesse et vous pouvez tolérer ~ 20% de fichiers plus gros, gzipc'est probablement votre meilleur pari.

Mise à jour: j'ai ajouté brotli(voir la réponse TOOGAMs) au tableau. brotlis réglage de la qualité de compression a un impact très important sur le taux de compression et la vitesse, alors j'ai ajouté trois paramètres ( q0, q1et q11). La valeur par défaut est q11, mais elle est extrêmement lente et encore pire que xz. q1semble très bien cependant; le même taux de compression gzip, mais 4 à 5 fois plus rapide!

Mise à jour: ajouté lbzip2(voir le commentaire de gmathts) et zstd(le commentaire de Johnny) au tableau, et trié par vitesse de compression. lbzip2remet la bzip2famille dans la course en compressant trois fois plus vite pbzip2qu'avec un excellent taux de compression! zstdsemble également raisonnable mais est battu brotli (q1)à la fois dans le rapport et la vitesse.

Ma conclusion initiale que la plaine gzipest le meilleur pari commence à paraître presque idiote. Bien que pour l'ubiquité, il ne peut toujours pas être battu;)

marcelm
la source
1
Pour une table similaire avec beaucoup plus d'algorithmes, voir mattmahoney.net/dc/text.html .
Dougal
1
@Dougal Assez juste. Mon test est sur des données similaires à celles de l'OP ( pg_dumpallsortie), donc c'est probablement un peu plus représentatif :)
marcelm
1
zstd est un autre qui manque dans le tableau - pour compresser nos fichiers journaux, j'ai trouvé qu'un processus zstd à cœur unique surpasse 16 cœurs de pbzip2 avec des taux de compression comparables.
Johnny
1
lz4est légèrement plus rapide et plus efficace que lzop, soit dit en passant. Il utilise cependant plus de RAM, ce qui est pertinent dans les systèmes embarqués.
Daniel B
1
Si vous souhaitez tester des versions multi-thread, vous pouvez zstd -T4également essayer . Pour les paramètres très rapides, vous pouvez essayer zstd -T4 -1, par zstddéfaut -3, qui est probablement le paramètre que vous avez testé.
Cyan
37

Utilisez pbzip2.

Le manuel dit:

pbzip2 est une implémentation parallèle du compresseur de fichiers de tri de blocs bzip2 qui utilise pthreads et permet une accélération quasi linéaire sur les machines SMP. La sortie de cette version est entièrement compatible avec bzip2 v1.0.2 ou plus récent (c'est-à-dire: tout ce qui est compressé avec pbzip2 peut être décompressé avec bzip2).

Il détecte automatiquement le nombre de processeurs dont vous disposez et crée des threads en conséquence.

ThoriumBR
la source
C'est bien si vous compressez un fichier, cela fonctionne horriblement à travers un tuyau
camelccc
@camelccc Pourquoi dites-vous cela? Je ne pense pas du tout que ce soit le cas. Vous avez besoin d'un producteur rapide ou d'un grand tampon sur le tuyau en face pour des performances optimales, mais c'est également vrai pour pixzet pigzsur un tuyau.
Michael - sqlbot
Cela dépend de la taille de ce qu'il compresse. Si vous avez un grand tampon, c'est bien comme vous le dites, si vous canalisez quelque chose qui est beaucoup plus grand qu'un ram physique, j'ai trouvé que les choses peuvent devenir plus intéressantes. Comme vous le dites, c'est probablement vrai pour tout algorithme de compression.
camelccc
4
bzip2 peut utiliser un peu de RAM, donc exécuter 16 travailleurs bzip à la fois pourrait consommer un ram non trivial, sur 1 Go. BTW, lbzip2semble donner une meilleure vitesse, une utilisation de la mémoire et une compression légèrement meilleure que pbzip2. Il y a des repères ici: vbtechsupport.com/1614
gmatht
@gmatht a l' lbzip2air sympa! Je l'ai ajouté à ma réponse :)
marcelm
8

Vous n'avez pas mentionné de système d'exploitation. Si Windows, 7-Zip avec ZStandard (versions) est une version de 7-Zip qui a été modifiée pour prendre en charge l'utilisation de tous ces algorithmes.

TOOGAM
la source
Intéressant, j'en avais déjà entendu parler brotli, mais je l'ai oublié. Je l'ai ajouté au tableau des repères dans ma réponse! J'étais en fait un peu déçu de ses performances, sauf au niveau de qualité 1, où il offrait le même taux de compression qu'à gzipune vitesse beaucoup plus élevée.
marcelm
2

Utilisez zstd . Si c'est assez bon pour Facebook, c'est probablement aussi assez bien pour vous.

Plus sérieusement, c'est en fait assez bon . Je l'utilise pour tout maintenant car cela fonctionne, et il vous permet d'échanger la vitesse pour un rapport à grande échelle (le plus souvent, la vitesse compte plus que la taille de toute façon car le stockage est bon marché, mais la vitesse est un goulot d'étranglement).
À des niveaux de compression qui atteignent une compression globale comparable à celle de bzip2, c'est beaucoup plus rapide, et si vous êtes prêt à payer un peu plus de temps CPU, vous pouvez presque obtenir des résultats similaires à LZMA (bien que ce sera plus lent que bzip2). À des taux de compression légèrement inférieurs, il est beaucoup, beaucoup plus rapide que bzip2 ou toute autre alternative traditionnelle.

Maintenant, vous compressez un vidage SQL, ce qui est à peu près aussi embarrassant que compressé. Même les compresseurs les plus pauvres obtiennent de bons résultats sur ce type de données.
Vous pouvez donc exécuter zstdavec un niveau de compression inférieur, qui s'exécutera des dizaines de fois plus rapidement et atteindra toujours 95 à 99% la même compression sur ces données.

En prime, si vous le faites souvent et que vous souhaitez investir un peu plus de temps, vous pouvez "entraîner" le zstdcompresseur à l'avance, ce qui augmente à la fois le taux de compression et la vitesse. Notez que pour que la formation fonctionne bien, vous devrez lui fournir des enregistrements individuels, pas le tout. De la façon dont l'outil fonctionne, il attend de nombreux petits échantillons quelque peu similaires pour la formation, pas un énorme blob.

Damon
la source
mieux encore, utilisez pzstd (version parallèle) sur les machines multicœurs
borowis
1

Il semble que l'ajustement (l'abaissement) de la taille du bloc puisse avoir un impact significatif sur le temps de compression.

Voici quelques résultats de l'expérience que j'ai faite sur ma machine. J'ai utilisé la timecommande pour mesurer le temps d'exécution. input.txtest un fichier texte de ~ 250 Mo contenant des enregistrements JSON arbitraires.

Utilisation de la taille de bloc par défaut (la plus grande) ( --bestsélectionne simplement le comportement par défaut):

# time cat input.txt | bzip2 --best > input-compressed-best.txt.bz

real    0m48.918s
user    0m48.397s
sys     0m0.767s

Utilisation de la plus petite taille de bloc ( --fastargument):

# time cat input.txt | bzip2 --fast > input-compressed-fast.txt.bz

real    0m33.859s
user    0m33.571s
sys     0m0.741s

Ce fut une découverte un peu surprenante, étant donné que la documentation dit:

La vitesse de compression et de décompression n'est pratiquement pas affectée par la taille du bloc

Jakub Kukul
la source
Mon préféré actuel est pbzip2. Avez-vous essayé cela aussi? Cette question concerne un environnement où 16 cœurs sont disponibles.
guettli
@guettli, malheureusement, je dois m'en tenir à bzip. Je l'utilise pour les travaux Hadoop et bzip est l'une des compressions intégrées là-bas. Donc, d'une certaine manière, c'est déjà parallélisé.
Jakub Kukul