pgzip: Compresión y Descompresión Gzip en Paralelo en Go

La biblioteca pgzip, desarrollada en Go, ofrece una solución para compresión y descompresión en paralelo utilizando el formato estándar gzip. Funciona como un reemplazo directo de la biblioteca nativa compress/gzip, pero con mejoras significativas en rendimiento y concurrencia, especialmente para grandes volúmenes de datos.


¿Por qué usar pgzip?

  • Procesamiento en paralelo: Divide la compresión en bloques para acelerar el proceso.
  • Compatible con gzip estándar: Los archivos comprimidos con pgzip pueden ser leídos por cualquier lector de gzip.
  • Descompresión eficiente: Permite la lectura anticipada (readahead), evitando bloqueos en la ejecución del código.
  • Optimización en CPU multinúcleo: Aprovecha el hardware para maximizar la velocidad de compresión y descompresión.
  • Manejo automático de CRC: La verificación de integridad se ejecuta en un hilo separado, mejorando la eficiencia.

Instalación

Para instalar la biblioteca, ejecuta:

go get github.com/klauspost/pgzip/...

También es recomendable actualizar las dependencias:

go get -u github.com/klauspost/compress

Uso de pgzip en Go

Compresión en paralelo

pgzip se usa de manera similar a compress/gzip, con la opción adicional de configurar el tamaño de bloque y la cantidad de bloques en paralelo.

package main

import (
    "bytes"
    "compress/gzip"
    "os"
    "github.com/klauspost/pgzip"
)

func main() {
    var b bytes.Buffer
    w := pgzip.NewWriter(&b)

    // Configurar concurrencia: 100 KB por bloque y hasta 10 bloques en paralelo.
    w.SetConcurrency(100000, 10)

    w.Write([]byte("Hola, mundo\n"))
    w.Close()

    // Guardar el archivo comprimido
    os.WriteFile("archivo.gz", b.Bytes(), 0644)
}

Explicación:

  • SetConcurrency(blockSize, blocks): Define el tamaño de bloque y el número de bloques en paralelo.
  • Valores recomendados:
    • Tamaño mínimo de bloque: 100 KB.
    • Número de bloques: Aproximadamente el doble del número de núcleos de la CPU.

Para notar mejoras de rendimiento, se recomienda comprimir archivos de más de 1 MB.


Descompresión en paralelo

La descompresión con pgzip es similar a compress/gzip, con la ventaja de permitir readahead (lectura anticipada) para mejorar el rendimiento.

package main

import (
    "os"
    "github.com/klauspost/pgzip"
)

func main() {
    f, err := os.Open("archivo.gz")
    if err != nil {
        panic(err)
    }
    defer f.Close()

    r, err := pgzip.NewReader(f)
    if err != nil {
        panic(err)
    }
    defer r.Close()

    contenido, err := os.ReadFile("archivo.gz")
    if err != nil {
        panic(err)
    }

    os.WriteFile("archivo.txt", contenido, 0644)
}

Si se necesita un control más preciso sobre la concurrencia, se puede usar:

r, err := pgzip.NewReaderN(f, blockSize, blocks)

Donde:

  • blockSize define el tamaño de los bloques a decodificar.
  • blocks define la cantidad de bloques a decodificar por adelantado.

Comparación de Rendimiento

Compresión (CPU de 16 núcleos, GOMAXPROC=32)

ComprimidorVelocidad (MB/s)AceleraciónTamaño finalSobrecarga (%)
gzip (Go estándar)16.91 MB/s1.0x4.78 GB0%
gzip (klauspost)127.10 MB/s7.52x4.88 GB+2.17%
pgzip (klauspost)2085.35 MB/s123.34x4.88 GB+2.19%

Observaciones:

  • pgzip es 123 veces más rápido que gzip estándar en esta prueba.
  • La sobrecarga en el tamaño del archivo es mínima (+2.19%) en comparación con gzip.
  • pgzip incluye un modo de compresión Huffman, que permite velocidades de hasta 450 MB/s por núcleo.

Descompresión (CPU de 4 núcleos)

DescompresorTiempoAceleración
gzip (Go estándar)1m 28.85s1.0x
pgzip (klauspost)43.48s2.04x

Conclusión:

  • pgzip es más del doble de rápido que gzip estándar.
  • La lectura anticipada (readahead) permite que los datos se procesen más rápido sin bloqueos de I/O.
  • La implementación actúa como buffer, evitando esperas innecesarias.

Conclusión

pgzip es una excelente opción para aplicaciones en Go que requieren compresión y descompresión eficiente en paralelo, especialmente en entornos de alto rendimiento. Sus principales ventajas incluyen:

Compatible con gzip estándar: No requiere cambiar herramientas o formatos.
Optimizado para grandes volúmenes de datos: Acelera procesamiento de archivos de más de 1 MB.
Soporte para CPU multinúcleo: Aprovecha el hardware para maximizar velocidad.
Compresión Huffman para ultra-rendimiento: Hasta 450 MB/s por núcleo.
Mejor rendimiento que gzip en Go: Hasta 123x más rápido en compresión y 2x más rápido en descompresión.

Si trabajas con grandes volúmenes de datos y necesitas compresión/descompresión eficiente en Go, pgzip es la mejor opción. 🚀

Suscríbete al boletín SysAdmin

Este es tu recurso para las últimas noticias y consejos sobre administración de sistemas, Linux, Windows, cloud computing, seguridad de la nube, etc. Lo enviamos 2 días a la semana.

¡Apúntate a nuestro newsletter!


– patrocinadores –

Noticias destacadas

– patrocinadores –

¡SUSCRÍBETE AL BOLETÍN
DE LOS SYSADMINS!

Scroll al inicio