Utilizando multi core para tar + gzip / bzip compresión / descompresión

225

Normalmente comprimo usando tar zcvfy descomprimo usando tar zxvf(usando gzip debido a la costumbre).

Recientemente obtuve una CPU de cuatro núcleos con hyperthreading, por lo que tengo 8 núcleos lógicos, y noto que muchos de los núcleos no se usan durante la compresión / descompresión.

¿Hay alguna forma de utilizar los núcleos no utilizados para hacerlo más rápido?

usuario1118764
fuente
La solución propuesta por Xiong Chiamiov arriba funciona maravillosamente. Acababa de hacer una copia de seguridad de mi computadora portátil con .tar.bz2 y me tomó 132 minutos usando solo un hilo de CPU. Luego compilé e instalé tar desde la fuente: gnu.org/software/tar . Incluí las opciones mencionadas en el paso de configuración: ./configure --with-gzip = pigz --with-bzip2 = lbzip2 --with-lzip = plzip Volví a ejecutar la copia de seguridad y me llevó solo 32 minutos. ¡Eso es mejor que la mejora 4X! Observé el monitor del sistema y mantenía los 4 cpus (8 hilos) planos al 100% todo el tiempo. Esa es la mejor solución.
Warren Severin el

Respuestas:

309

Puede usar pigz en lugar de gzip, que hace la compresión gzip en múltiples núcleos. En lugar de usar la opción -z, lo canalizarías a través de pigz:

tar cf - paths-to-archive | pigz > archive.tar.gz

Por defecto, pigz usa el número de núcleos disponibles, u ocho si no puede consultar eso. Puede pedir más con -pn, por ejemplo, -p 32. pigz tiene las mismas opciones que gzip, por lo que puede solicitar una mejor compresión con -9. P.ej

tar cf - paths-to-archive | pigz -9 -p 32 > archive.tar.gz
Mark Adler
fuente
3
¿Cómo se usa pigz para descomprimir de la misma manera? ¿O solo funciona para la compresión?
user788171
42
pigz usa múltiples núcleos para la descompresión, pero solo con una mejora limitada sobre un solo núcleo. El formato desinflado no se presta a la descompresión paralela. La parte de descompresión debe hacerse en serie. Los otros núcleos para la descompresión pigz se usan para leer, escribir y calcular el CRC. Por otro lado, al comprimir, pigz se acerca a un factor de n mejora con n núcleos.
Mark Adler
77
El guión aquí es estándar (vea esta página ).
Garrett
3
Si. 100% compatible en ambas direcciones.
Mark Adler
44
Efectivamente, no hay tiempo de CPU dedicado a las tareas, por lo que no ayudaría mucho. El formato tar es solo una copia del archivo de entrada con bloques de encabezado entre archivos.
Mark Adler el
324

También puede usar el indicador tar "--use-compress-program =" para decirle a tar qué programa de compresión usar.

Por ejemplo, use:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip 
Jen
fuente
21
Esta es una pequeña pepita de conocimiento increíble y merece más votos a favor. No tenía idea de que esta opción existía y he leído la página del manual varias veces a lo largo de los años.
Randall Hunt el
2
@ValerioSchiavoni: No aquí, obtengo carga completa en los 4 núcleos (Ubuntu 15.04 'Vivid').
bovender
8
Prefiero tar - dir_to_zip | pv | pigz > tar.filepv me ayuda a estimar, puedes omitirlo. Pero aún así es más fácil escribir y recordar.
Offenso
@ NathanS.Watson-Haigh Sí, ¿verdad? Simplemente incluya el nombre del programa y los argumentos entre comillas. man tarlo dice, como hace esto .
Marc.2377
1
En 2020, zstdes la herramienta más rápida para hacer esto. Notable aceleración al comprimir y descomprimir. Se utiliza tar -cf --use-compress-program=zstdmtpara hacerlo con subprocesos múltiples.
Jadelord
112

Enfoque común

Hay una opción para el tarprograma:

-I, --use-compress-program PROG
      filter through PROG (must accept -d)

Puede usar la versión multiproceso del archivador o la utilidad del compresor.

Los archivadores multiproceso más populares son pigz (en lugar de gzip) y pbzip2 (en lugar de bzip2). Por ejemplo:

$ tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 paths_to_archive
$ tar --use-compress-program=pigz -cf OUTPUT_FILE.tar.gz paths_to_archive

El archivador debe aceptar -d. Si su utilidad de reemplazo no tiene este parámetro y / o necesita especificar parámetros adicionales, entonces use tuberías (agregue parámetros si es necesario):

$ tar cf - paths_to_archive | pbzip2 > OUTPUT_FILE.tar.gz
$ tar cf - paths_to_archive | pigz > OUTPUT_FILE.tar.gz

La entrada y salida de subprocesos simples y múltiples son compatibles. Puede comprimir usando la versión multiproceso y descomprimir usando la versión de un solo hilo y viceversa.

p7zip

Para p7zip para la compresión, necesita un pequeño script de shell como el siguiente:

#!/bin/sh
case $1 in
  -d) 7za -txz -si -so e;;
   *) 7za -txz -si -so a .;;
esac 2>/dev/null

Guárdelo como 7zhelper.sh. Aquí el ejemplo de uso:

$ tar -I 7zhelper.sh -cf OUTPUT_FILE.tar.7z paths_to_archive
$ tar -I 7zhelper.sh -xf OUTPUT_FILE.tar.7z

xz

Respecto al soporte XZ multiproceso. Si está ejecutando la versión 5.2.0 o superior de XZ Utils, puede utilizar múltiples núcleos para la compresión configurando -To --threadsen un valor apropiado a través de la variable de entorno XZ_DEFAULTS (por ejemplo XZ_DEFAULTS="-T 0").

Este es un fragmento de man para la versión 5.1.0alpha:

La compresión y descompresión multiproceso aún no se han implementado, por lo que esta opción no tiene ningún efecto por el momento.

Sin embargo, esto no funcionará para la descompresión de archivos que tampoco se han comprimido con el subproceso habilitado. Desde man para la versión 5.2.2:

La descompresión roscada aún no se ha implementado. Solo funcionará en archivos que contienen múltiples bloques con información de tamaño en los encabezados de bloque. Todos los archivos comprimidos en modo de subprocesos múltiples cumplen esta condición, pero los archivos comprimidos en modo de subprocesos simples ni siquiera si se usa --block-size = size.

Recompilación con reemplazo

Si crea tar desde las fuentes, puede volver a compilar con parámetros

--with-gzip=pigz
--with-bzip2=lbzip2
--with-lzip=plzip

Después de volver a compilar tar con estas opciones, puede consultar el resultado de la ayuda de tar:

$ tar --help | grep "lbzip2\|plzip\|pigz"
  -j, --bzip2                filter the archive through lbzip2
      --lzip                 filter the archive through plzip
  -z, --gzip, --gunzip, --ungzip   filter the archive through pigz
Maxim Suslov
fuente
1
Esta es de hecho la mejor respuesta. Definitivamente voy a reconstruir mi alquitrán!
1
Acabo de encontrar pbzip2 y mpibzip2 . mpibzip2 parece muy prometedor para clústeres o si tiene una computadora portátil y una computadora de escritorio multinúcleo, por ejemplo.
Esta es una respuesta excelente y elaborada. Puede ser bueno mencionar que la compresión multiproceso (por ejemplo, con pigz) solo está habilitada cuando se lee desde el archivo. El procesamiento de STDIN puede, de hecho, ser más lento.
oᴉɹǝɥɔ
3
Más 1 para la xzopción. Es el enfoque más simple pero efectivo.
selurvedu
2
export XZ_DEFAULTS="-T 0"antes de llamar tarcon la opción -Jde compresión xz funciona de maravilla.
scai
13

Puede usar el acceso directo -Ipara el --use-compress-programcambio de tar e invocar pbzip2para la compresión bzip2 en múltiples núcleos:

tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/
panticz
fuente
Un buen TL; DR para la respuesta de @ MaximSuslov .
einpoklum
Esto devuelve tar: home/cc/ziptest: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors`
Arash
1

Si desea tener más flexibilidad con los nombres de archivo y las opciones de compresión, puede usar:

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec \
tar -P --transform='s@/my/path/@@g' -cf - {} + | \
pigz -9 -p 4 > myarchive.tar.gz

Paso 1: find

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec

Este comando buscará los archivos que desea archivar, en este caso /my/path/*.sqly /my/path/*.log. Agrega tantos -o -name "pattern"como quieras.

-execejecutará el siguiente comando usando los resultados de find:tar

Paso 2: tar

tar -P --transform='s@/my/path/@@g' -cf - {} +

--transformes un simple parámetro de reemplazo de cadena. Eliminará la ruta de los archivos del archivo para que la raíz del tarball se convierta en el directorio actual cuando se extraiga. Tenga en cuenta que no puede usar la -Copción para cambiar el directorio, ya que perderá los beneficios de find: se incluirán todos los archivos del directorio.

-Ple indica tarque use rutas absolutas, por lo que no activa la advertencia "Eliminando los principales '/' de los nombres de los miembros". La '/' inicial se eliminará de --transformtodos modos.

-cf -le dice tarque use el nombre tarball que especificaremos más adelante

{} +usa todos los archivos que findencontraste previamente

Paso 3: pigz

pigz -9 -p 4

Use tantos parámetros como desee. En este caso -9es el nivel de compresión y -p 4es el número de núcleos dedicados a la compresión. Si ejecuta esto en un servidor web cargado, probablemente no quiera usar todos los núcleos disponibles.

Paso 4: nombre del archivo

> myarchive.tar.gz

Finalmente.

Bloops
fuente
0

Una herramienta de compresión (de) relativamente más nueva que quizás desee considerar es zstandard . Hace un excelente trabajo al utilizar núcleos de repuesto, y ha hecho algunas grandes compensaciones en lo que respecta a la relación de compresión frente al (des) tiempo de compresión. También es altamente modificable dependiendo de sus necesidades de relación de compresión.

pgebhard
fuente