Tiempo para comprimir archivos muy grandes (100G)

27

Me encuentro teniendo que comprimir una cantidad de archivos muy grandes (80-GB GB), y me sorprende la (falta de) velocidad que exhibe mi sistema. Obtengo aproximadamente 500 MB / min de velocidad de conversión; usando top, parece que estoy usando una sola CPU al 100% aproximadamente.

Estoy bastante seguro de que no es (solo) la velocidad de acceso al disco, ya que crear un tararchivo (así fue como se creó el archivo 80G) tomó solo unos minutos (tal vez 5 o 10), pero después de más de 2 horas mi simple comando gzip sigue siendo no hecho

En resumen:

tar -cvf myStuff.tar myDir/*

Tomó <5 minutos para crear un archivo tar 87 G

gzip myStuff.tar

Tomó dos horas y 10 minutos, creando un archivo zip 55G.

Mi pregunta: ¿es esto normal? ¿Hay ciertas opciones gzippara acelerar las cosas? ¿Sería más rápido concatenar los comandos y usarlos tar -cvfz? Yo referencia a la sierra pigz- aplicación paralela de GZip - pero por desgracia no puedo instalar el software en la máquina que estoy utilizando, por lo que no es una opción para mí. Ver por ejemplo esta pregunta anterior .

Tengo la intención de probar algunas de estas opciones yo mismo y cronometrarlas, pero es muy probable que no llegue a "la combinación mágica" de opciones. Espero que alguien en este sitio conozca el truco correcto para acelerar las cosas.

Cuando tenga los resultados de otras pruebas disponibles, actualizaré esta pregunta, pero si alguien tiene un truco particularmente bueno disponible, realmente lo agradecería. Tal vez el gzip solo requiere más tiempo de procesamiento del que me di cuenta ...

ACTUALIZAR

Como prometí, probé los trucos que se sugieren a continuación: cambiar la cantidad de compresión y cambiar el destino del archivo. Obtuve los siguientes resultados para un alquitrán de aproximadamente 4.1 GB:

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

Entonces, sí, cambiar la bandera de la predeterminada -6a la más rápida -1me da una aceleración del 30%, con (para mis datos) casi ningún cambio en el tamaño del archivo zip. Si estoy usando el mismo disco u otro, esencialmente no hace ninguna diferencia (tendría que ejecutar esto varias veces para obtener alguna significación estadística).

Si alguien está interesado, generé estos puntos de referencia de tiempo utilizando los siguientes dos scripts:

#!/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

Y el segundo 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

Tres cosas a tener en cuenta:

  1. Usar en /usr/bin/timelugar de time, ya que el comando incorporado de bashtiene muchas menos opciones que el comando GNU
  2. No me molesté en usar la --formatopción, aunque eso facilitaría la lectura del archivo de registro
  3. Utilicé un script en un script ya que timeparecía funcionar solo con el primer comando en una secuencia canalizada (por lo que lo hice ver como un solo comando ...).

Con todo esto aprendido, mis conclusiones son

  1. Acelera las cosas con la -1bandera (respuesta aceptada)
  2. Se gasta mucho más tiempo comprimiendo los datos que leyendo desde el disco
  3. Invierta en un software de compresión más rápido ( pigzparece una buena opción).
  4. Si tiene varios archivos para comprimir, puede colocar cada gzipcomando en su propio hilo y usar más de la CPU disponible (pobre pigz)

¡Gracias a todos los que me ayudaron a aprender todo esto!

Floris
fuente
tar -cvf no hace ninguna compresión, por lo que será más rápido
parkydr
2
@Floris: ¿qué tipo de datos estás tratando de comprimir? nota al margen: $> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gzle mostrará qué tan rápido su máquina está comprimiendo las cosas. nota lateral2: almacena el resultado en un disco diferente.
akira
3
Lo siento, leí mal tu pregunta. gzip tiene la opción --fast para seleccionar el más rápido de compresión
parkydr
1
@parkydr: La opción --fast es una que no conocía ... es la última en la manpágina, y no leí tan lejos (porque está ordenada por 'comando de letra única', que es -#) . ¡Eso me enseñará a RTFM! ¡Esto será lo próximo que intentaré!
Floris
2
Tenga en cuenta que si un compilador adecuado está disponible en la máquina, y los permisos del sistema de archivos no están configurados para prohibir la ejecución de archivos binarios desde los directorios a los que tiene acceso, puede compilarlo pigzy ejecutarlo desde cualquier lugar donde lo haya compilado , sin instalarlo. Si no hay un compilador, puede realizar una compilación cruzada en otra computadora, aunque eso está comenzando a requerir más esfuerzo del que podría valer la pena. (Dependiendo de cuánto necesita esta compresión para correr más rápido, supongo).
David Z

Respuestas:

27

Puede cambiar la velocidad de gzip usando --fast --besto -#donde # es un número entre 1 y 9 (1 es más rápido pero menos compresión, 9 es más lento pero más compresión). Por defecto, gzip se ejecuta en el nivel 6.

robingrindrod
fuente
26

La razón por la que tar tarda tan poco tiempo en comparación con gzip es que hay muy poca sobrecarga computacional al copiar sus archivos en un solo archivo (que es lo que hace). gzip por otro lado, en realidad está usando algoritmos de compresión para reducir el archivo tar.

El problema es que gzip está restringido (como descubrió) a un solo hilo.

Ingrese pigz , que puede usar múltiples hilos para realizar la compresión. Un ejemplo de cómo usar esto sería:

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

Hay un resumen sucinto de la opción --use-compress-program en un sitio hermano .

Steve Gore
fuente
Gracias por su respuesta y enlaces. De hecho, mencioné pigz en la pregunta.
Floris
Esta es la respuesta correcta aquí ...!
stolsvik
4

Parece que estoy usando una sola CPU a aproximadamente el 100%.

Eso implica que no hay un problema de rendimiento de E / S, pero que la compresión solo usa un hilo (que será el caso con gzip).

Si logra lograr el acceso / acuerdo necesario para instalar otras herramientas, entonces 7zip también admite múltiples hilos para aprovechar las CPU de múltiples núcleos, aunque no estoy seguro de si eso se extiende tanto al formato gzip como al suyo.

Si está atascado a usar solo gzip por el momento y tiene varios archivos para comprimir, puede intentar comprimirlos individualmente, de esa manera usará más de esa CPU de múltiples núcleos ejecutando más de un proceso en paralelo. Sin embargo, tenga cuidado de no exagerar porque tan pronto como se acerque a la capacidad de su subsistema de E / S, el rendimiento disminuirá precipitadamente (más bajo que si estuviera usando un proceso / hilo) ya que la latencia de los movimientos de la cabeza se vuelve significativa embotellamiento.

David Spillett
fuente
Gracias por tu contribución. Me diste una idea (para la cual obtienes un voto positivo): como tengo varios archivos para crear, puedo escribir los comandos individuales seguidos de un &- y luego dejar que el sistema se encargue de eso. Cada uno se ejecutará en su propio procesador, y dado que paso mucho más tiempo en compresión que en E / S, me tomará el mismo tiempo hacer uno que hacer los 10. Así que obtengo "rendimiento de núcleo múltiple" de un ejecutable que tiene un solo subproceso ...
Floris
1

También se puede aprovechar la cantidad de procesos disponibles en pigz, que generalmente es un rendimiento más rápido, como se muestra en el siguiente comando

tar cf - directorio para archivar | pigz -0 -p largenumber> mydir.tar.gz

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

Esto es probablemente más rápido que los métodos sugeridos en la publicación, ya que -p es la cantidad de procesos que uno puede ejecutar. En mi experiencia personal, establecer un valor muy grande no perjudica el rendimiento si el directorio a archivar consiste en una gran cantidad de archivos pequeños. De lo contrario, el valor predeterminado considerado es 8. Para archivos grandes, mi recomendación sería establecer este valor como el número total de subprocesos admitidos en el sistema.

Ejemplo de configuración de un valor de p = 32 en el caso de una máquina de 32 CPU ayuda.

0 está destinado a la compresión pigz más rápida, ya que no comprime el archivo y se centra en la velocidad. El valor predeterminado es 6 para la compresión.

Ankit Shah
fuente