bzip2 demasiado lento Múltiples núcleos disponibles.

31

Estoy ejecutando este comando:

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

Toma mucho tiempo Miro los procesos con top. El proceso bzip2 toma alrededor del 95% y postgres 5% de un núcleo. La waentrada es baja. Esto significa que el disco no es el cuello de botella.

¿Qué puedo hacer para aumentar el rendimiento?

Quizás deje que bzip2 use más núcleos. Los servidores tienen 16 núcleos.

¿O usar una alternativa a bzip2?

¿Qué puedo hacer para aumentar el rendimiento?

guettli
fuente
8
A menos que necesite bzip2 por razones heredadas, ha sido mi experiencia personal que xz proporciona una mejor compresión / tiempo que bzip2. También se enhebra si obtienes un programa lo suficientemente nuevo, y te permite escalar el tiempo y el uso de memoria de gzipish a masivo dependiendo de lo que quieras.
Perkins
66
"pigz" es otra opción: produce salida gzip en lugar de salida bzip2. Y básicamente todo entiende gzip.
Criggie
Puede intentar cifrarlo simétricamente con GnuPG con compresión bzip2; parece sorprendentemente rápido en comparación con solo comprimirlo, por alguna razón desconocida, incluso con el nivel de compresión más alto. Es posible que el algoritmo sea más rápido que la eficiencia de mi programa de compresión regular, que está basado en GUI.
Shule
2
No ha indicado los requisitos de su algoritmo alternativo. Bzip2 es divisible. ¿Es importante para ti?
Martin Smith
77
" ¿Qué puedo hacer para aumentar el rendimiento? ", ¿No comprimirlo? En realidad, no dice que lo necesita comprimido, y no hacer trabajo siempre es más rápido que hacer trabajo. Haga que el disco sea el cuello de botella.
TessellatingHeckler

Respuestas:

49

Hay muchos algoritmos de compresión, y bzip2es uno de los más lentos. La llanura gziptiende a ser significativamente más rápida, generalmente con una compresión no mucho peor. Cuando la velocidad es lo más importante, lzopes mi favorito. Mala compresión, pero tan rápido.

Decidí divertirme un poco y comparar algunos algoritmos, incluidas sus implementaciones paralelas. El archivo de entrada es la salida del pg_dumpallcomando en mi estación de trabajo, un archivo SQL de 1913 MB. El hardware es un i5 de cuatro núcleos más antiguo. Los tiempos son tiempos de reloj de pared de solo la compresión. Las implementaciones paralelas están configuradas para usar los 4 núcleos. Tabla ordenada por velocidad de compresión.

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 los 16 núcleos de su servidor están lo suficientemente inactivos como para que todos puedan usarse para la compresión, pbzip2probablemente le dará una aceleración muy significativa. Pero aún necesita más velocidad y puede tolerar archivos ~ 20% más grandes, gzipes probablemente su mejor opción.

Actualización: agregué brotli(ver respuesta de TOOGAM) resultados a la tabla. brotlis ajuste de calidad de compresión tiene un impacto muy grande en relación de compresión y la velocidad, por lo que añade tres ajustes ( q0, q1y q11). El valor predeterminado es q11, pero es extremadamente lento y aún peor xz. q1aunque se ve muy bien; ¡la misma relación de compresión que gzip, pero 4-5 veces más rápido!

Actualización: Se agregó lbzip2(ver comentario de gmathts) y zstd(comentario de Johnny) a la tabla, y se ordenó por velocidad de compresión. lbzip2¡pone a la bzip2familia nuevamente en funcionamiento al comprimir tres veces más rápido que pbzip2con una excelente relación de compresión! zstdTambién parece razonable, pero es superado brotli (q1)tanto en relación como en velocidad.

Mi conclusión original de que gzipes la mejor apuesta es comenzar a parecer casi tonto. Aunque por ubicuidad, aún no se puede superar;)

marcelm
fuente
1
Para obtener una tabla similar con muchos más algoritmos, consulte mattmahoney.net/dc/text.html .
Dougal
1
@Dougal lo suficientemente justo. Mi prueba es en datos similares como el PO, aunque ( pg_dumpallde salida), por lo que es probablemente un poco más representativa :)
marcelm
1
zstd es otro que falta en la tabla: para comprimir nuestros archivos de registro, descubrí que un solo proceso zstd de núcleo supera 16 núcleos de pbzip2 con relaciones de compresión comparables.
Johnny
1
lz4es un poco más rápido y más eficiente que lzop, por cierto. Sin embargo, utiliza más RAM, lo cual es relevante en los sistemas integrados.
Daniel B
1
Si está dispuesto a probar versiones multiproceso, también puede intentarlo zstd -T4. Para configuraciones muy rápidas, puede probar zstd -T4 -1, por zstddefecto -3, cuál es probablemente la configuración que probó.
Cian
37

Usa pbzip2.

El manual dice:

pbzip2 es una implementación paralela del compresor de archivos de clasificación de bloques bzip2 que usa pthreads y logra una aceleración casi lineal en máquinas SMP. El resultado de esta versión es totalmente compatible con bzip2 v1.0.2 o posterior (es decir: cualquier cosa comprimida con pbzip2 puede descomprimirse con bzip2).

Detecta automáticamente la cantidad de procesadores que tiene y crea subprocesos en consecuencia.

ThoriumBR
fuente
Eso está bien si está comprimiendo un archivo, sin embargo, esto funciona horriblemente a través de una tubería
camelccc
@camelccc ¿Por qué dices eso? No creo que ese sea el caso, en absoluto. Necesita un productor rápido o un gran amortiguador en la tubería frente a él para un rendimiento óptimo, pero eso es igualmente cierto para pixzy pigzen una tubería también.
Michael - sqlbot
Depende de cuán grande sea lo que esté comprimiendo. Si tiene un búfer grande, está bien, como dice, si está conectando algo que es mucho más grande que el carnero físico, he descubierto que las cosas pueden ser bastante más interesantes. Sin embargo, como dices probablemente sea cierto para cualquier algoritmo de compresión.
camelccc
44
bzip2 puede usar un poco de ram, por lo que ejecutar 16 trabajadores de bzip a la vez podría consumir ram no trivial, más de 1GB. Por cierto, lbzip2parece dar una mejor velocidad, uso de memoria y una compresión marginalmente mejor que pbzip2. Aquí hay puntos de referencia: vbtechsupport.com/1614
gmatht
@gmatht se lbzip2ve bien! Lo agregué a mi respuesta :)
marcelm
8

No mencionaste un sistema operativo. Si Windows, 7-Zip con ZStandard (versiones) es una versión de 7-Zip que se ha modificado para proporcionar soporte para el uso de todos estos algoritmos.

TOOGAM
fuente
Interesante, había escuchado brotliantes, pero lo olvidé. ¡Lo agregué a la tabla de puntos de referencia en mi respuesta! De hecho, estaba un poco decepcionado con su rendimiento, excepto en el ajuste de calidad 1, donde proporcionaba la misma relación de compresión que gzipa una velocidad mucho mayor.
marcelm
2

Usa zstd . Si es lo suficientemente bueno para Facebook, probablemente también sea lo suficientemente bueno para ti.

En una nota más seria, en realidad es bastante bueno . Lo uso para todo ahora porque simplemente funciona, y le permite cambiar la velocidad por la relación a gran escala (la mayoría de las veces, la velocidad importa más que el tamaño, ya que el almacenamiento es barato, pero la velocidad es un cuello de botella).
A niveles de compresión que alcanzan una compresión general comparable a bzip2, es significativamente más rápido, y si está dispuesto a pagar un poco más en tiempo de CPU, casi puede lograr resultados similares a LZMA (aunque entonces será más lento que bzip2). Con tasas de compresión ligeramente peores, es mucho, mucho más rápido que bzip2 o cualquier otra alternativa convencional.

Ahora, está comprimiendo un volcado de SQL, que es tan vergonzosamente trivial para comprimir como puede ser. Incluso los compresores más pobres obtienen buenos puntajes en ese tipo de datos.
Por lo tanto, puede ejecutar zstdcon un nivel de compresión más bajo, que se ejecutará docenas de veces más rápido y aún alcanzará el 95-99% de la misma compresión en esos datos.

Como beneficio adicional, si va a hacer esto con frecuencia y desea invertir algo de tiempo extra, puede "entrenar" el zstdcompresor con anticipación, lo que aumenta tanto la relación de compresión como la velocidad. Tenga en cuenta que para que el entrenamiento funcione bien, necesitará alimentar registros individuales, no todo. La forma en que funciona la herramienta, espera muchas muestras pequeñas y algo similares para el entrenamiento, no una gran gota.

Damon
fuente
mejor aún, use pzstd (versión paralela) en máquinas multinúcleo
borowis
1

Parece que ajustar (bajar) el tamaño del bloque puede tener un impacto significativo en el tiempo de compresión.

Aquí hay algunos resultados del experimento que hice en mi máquina. Usé el timecomando para medir el tiempo de ejecución. input.txtes un archivo de texto de ~ 250 mb que contiene registros json arbitrarios.

Usando el tamaño de bloque predeterminado (más grande) ( --bestsimplemente selecciona el comportamiento predeterminado):

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

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

Usando el tamaño de bloque más pequeño ( --fastargumento):

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

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

Este fue un descubrimiento un poco sorprendente, teniendo en cuenta que la documentación dice:

La velocidad de compresión y descompresión prácticamente no se ve afectada por el tamaño del bloque

Jakub Kukul
fuente
Mi favorito actual es pbzip2. ¿Has probado esto también? Esta pregunta es sobre un entorno donde hay 16 núcleos disponibles.
guettli
@guettli desafortunadamente tengo que seguir con bzip. Lo estoy usando para trabajos de Hadoop y bzip es una de las compresiones incorporadas allí. Entonces, en cierto modo, ya está en paralelo.
Jakub Kukul