Comprimir muchos archivos grandes similares

18

Tengo cientos de archivos grandes similares (30 megabytes cada uno) que quiero comprimir. Cada par de archivos tiene el 99% de los mismos datos (menos de 1% de diferencia), por lo que espero no tener más de 40-50 megabytes de archivos.

Una sola fila puede ser comprimido de 30 MB a 13-15 MB (con xz -1, gz -1, bzip2 -1), pero cuando la compresión de dos o más archivos que desea tener el tamaño de archivo con 13-15MB + N*0.3MBel que N es el número de archivos.

Cuando uso tar(para crear un archivo sólido) y xz -6(para definir que el diccionario de compresión sea más grande que un archivo - Actualización - ¡esto no fue suficiente! ), Todavía tengo un archivo con tamaño N*13MB.

Creo que ambos gzipy bzip2no me ayudarán porque tienen un diccionario de menos de 1 MB, y mi transmisión tar tiene repeticiones cada 30 MB.

¿Cómo puedo archivar mi problema en Linux moderno usando herramientas estándar?

¿Es posible sintonizar xzpara comprimir rápidamente, pero usar un diccionario de más de 30-60 MB?

Actualización : hizo el truco con tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. No estoy seguro acerca de lo necesario mf=hc4y las --memory=2Gopciones; pero dict=128Mconfigure el diccionario para que sea lo suficientemente grande (más grande que un archivo) y mode=fasthaga que el proceso sea un poco más rápido que -e.

osgx
fuente
Ejecutar xz -1 --memory=2Gno ayudó, probado en 2 y 4 archivos del conjunto.
osgx

Respuestas:

12

Teniendo en cuenta sus detalles, supongo que ha verificado que sus archivos realmente tienen el 99% de datos en común, con un 1% contiguo (o casi contiguo) de diferencia en ellos.

Primero, debe usar tar para hacer un archivo con sus archivos dentro. Para las pruebas, crearía un .tar con 10 archivos, con un tamaño de 300 MB.

Luego, usando xz, debe configurarlo para que el diccionario sea más grande que el tamaño de un archivo. Como no dices si tienes restricciones de memoria, usaría xz -9. No tiene sentido no usar toda la memoria disponible.

También usaría el preajuste --extreme, para probar si hace la diferencia.

Tamaño del diccionario

En una documentación que tengo disponible, sitio , se dice que el tamaño del diccionario es aproximadamente igual al uso de la memoria del descompresor. Y el parámetro -1 significa un dict de 1MiB, -6 significa 10 MiB (u 8 MiB en otra parte del mismo manual). Es por eso que no obtienes ninguna ventaja al agrupar esos archivos. Usar el -9 haría que el descompensor (y, por lo tanto, el diccionario) sea 64 MiB, y creo que eso es lo que querías.

Editar

Otra posibilidad sería usar otro compresor. Iría con 7zip, pero primero alquilaría esos archivos y luego los comprimiría.

Dependiendo del contenido de sus archivos, quizás podría usar 7zip con el método PPM-D (en lugar de LZMA o LZMA2, ese es el valor predeterminado y el mismo que usa xz)

No es bueno: Zip (dict = 32kB), Bzip (dict = 900 kB).

woliveirajr
fuente
Xz y 7-Zip usan LZMA2, por lo que no habrá ningún beneficio allí. PPMD está optimizado para la extracción de entropía extremadamente lenta pero de alta tasa de compresión de medios ya comprimidos (por ejemplo, MP3 y video). No es particularmente probable encontrar las grandes similitudes entre los dos archivos y almacenarlos en el diccionario, no es más probable que LZMA2.
allquixotic
woliveirajr, ¿qué pasa con el uso de not -1o -9preset, pero especificar dict=64MBo dict=128MBy establecer mode=fast?
osgx
El uso de dict = xxMB en lugar de -1 o -9 iría directamente al grano, pero como no sé cómo xz establece otros parámetros cuando solo usas -9, no sé si no te perderías algo más. Creo que estás en la dirección correcta, y solo la prueba te dará una respuesta precisa.
woliveirajr
3
Con xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2Gpude comprimir 250 archivos (7,5 GB) a 18 MB de archivo tar.xz.
osgx
@osgx :) eso es bastante bueno. Si no tomó demasiado tiempo (es decir, está dentro de sus necesidades), ¡problema resuelto! :) Así que tienes final_size = 13MB + x * 6kB, más o menos.
woliveirajr
9

Si realmente son 99% similares a lo que usted dice, debería poder usar bsdiff o un algoritmo similar para calcular las diferencias entre los archivos. ¿Es la diferencia acumulativa (es decir, cada archivo difiere un poco más del primero) o la diferencia entre dos archivos es prácticamente la misma?

Si no es acumulativo, debería poder:

  • Tome cualquier archivo arbitrario como "línea de base"
  • Ejecute la bsdiffcomparación del archivo de referencia con cada archivo adicional
  • Almacene cada diff como un archivo separado, junto con el archivo de línea de base
  • Ejecute un compresor como a xztravés de los resultados (la línea de base + las diferencias).

El resultado debería ser mucho más pequeño que solo xzel archivo completo.

Luego puede "reconstituir" los archivos originales al "aplicar" el diferencial en la parte superior de la línea de base para obtener cada uno de los otros archivos.

allquixotic
fuente
No acumulable ("Cada par de archivos tiene el 99% de los mismos datos ...")
osgx
1
Si las diferencias no son acumulativas, esta debería ser una buena aplicación del bsdiffalgoritmo. Darle una oportunidad.
allquixotic
Gracias por su respuesta, pero ya hice la tarea con xz: tar c directory|xz --lzma2=dict=128M,mode=fasty eliminé los archivos de entrada. En realidad, mis archivos de entrada eran texto, por lo que incluso puedo usar diff en lugar de bsdiff(que no está instalado en mi PC).
osgx
5

Usted (I) puede usar tar con algún archivador capaz de detectar patrones de largo alcance, por ejemplo, rzip o lrzip ( Léame ). Ambos usan detección / deduplicación de redundancia de largo alcance, luego rzip usa bzip2 y lrzip usa xz (lzma) / ZPAQ:

rzip es un programa de compresión, similar en funcionalidad a gzip o bzip2, pero capaz de aprovechar las redundancias de larga distancia en los archivos, lo que a veces puede permitir que rzip produzca relaciones de compresión mucho mejores que otros programas. ... La principal ventaja de rzip es que tiene un búfer de historial efectivo de 900 Mbyte. Esto significa que puede encontrar partes coincidentes del archivo de entrada a grandes distancias en comparación con otros programas de compresión de uso común. En comparación, el programa gzip usa un búfer de historial de 32 kbytes y bzip2 usa un búfer de historial de 900 kbytes

lrzip tiene un búfer más grande y puede usar muchos algoritmos de compresión (muy rápido, rápido, bueno y uno de los mejores, ZPAQ) después de la deduplicación:

Lrzip utiliza una versión extendida de rzip que realiza una reducción de redundancia de larga distancia de primer paso. Las modificaciones de lrzip hacen que se escale de acuerdo con el tamaño de la memoria.

Los datos son: 1. Comprimidos por lzma (predeterminado) que proporciona una compresión excelente a aproximadamente el doble de la velocidad de compresión bzip2 ...

Otra forma es usar bup - programa de respaldo con deduplicación a nivel de bloque / segmento, basado en git packfile:

Utiliza un algoritmo de suma de comprobación continua (similar a rsync) para dividir archivos grandes en fragmentos.

osgx
fuente