高效能 gzip 壓縮工具 pgzip

bupt_xingxin發表於2021-10-18

背景

gzip 是當前應用非常廣泛的檔案壓縮格式,golang 中也有內建的 compress/gzip 對其提供原生支援。今天我們要介紹的 pgzip 是一款完全相容 gzip 的外掛,並能提供相較於 compress/gzip 上百倍的效能提升!

pgzip 簡介

pgzip(https://github.com/klauspost/pgzip) 主要是通過分塊並行壓縮實現效能提升的,尤其適用於大量資料(>1MB)壓縮的場景。由於 pgzip 的 API 設計完全相容 compress/gzip,因此我們的工程升級到 pgzip 只需要特別小的改動:

import gzip "github.com/klauspost/pgzip"

另外,pgzip 還支援指定併發度,我們可以據此對壓縮消耗的 CPU 資源進行管控;pgzip 還附帶了一個線性時間壓縮模式(Huffman only compression),該模式支援以每核每秒約 250MB 的速度進行資料壓縮。

應用舉例

隨機生成一個 100MB 的大檔案作為待壓縮檔案:

dd if=/dev/random of=data.bin bs=4m count=25

首先使用原生的 compress/gzip 進行壓縮:

package main

import (
    "compress/gzip"
    "io"
    "log"
    "os"
)

func main() {
    fr, err := os.Open("data.bin")
    if err != nil {
        log.Fatalf("failed to open file to read: %v", err)
    }
    defer fr.Close()

    fw, err := os.Create("gzip_res.gz")
    if err != nil {
        log.Fatalf("failed to open file to write: %v", err)
    }
    defer fw.Close()

    w := gzip.NewWriter(fw)
    defer w.Close()
    _, err = io.Copy(w, fr)
    if err != nil {
        log.Fatalf("failed to gzip: %v", err)
    }
}

檢視執行時間:

$ go build -o gzip_demo
$ time ./gzip_demo
./gzip_demo  1.86s user 0.23s system 99% cpu 2.111 total

現在我們切換到 pgzip 對同樣的檔案進行壓縮:

package main

import (
    "io"
    "log"
    "os"

    gzip "github.com/klauspost/pgzip"
)

func main() {
    fr, err := os.Open("data.bin")
    if err != nil {
        log.Fatalf("failed to open file to read: %v", err)
    }
    defer fr.Close()

    fw, err := os.Create("pgzip_res.gz")
    if err != nil {
        log.Fatalf("failed to open file to write: %v", err)
    }
    defer fw.Close()

    w := gzip.NewWriter(fw)
    defer w.Close()
    // 1MB block with 4 concurrency
    w.SetConcurrency(1<<20, 4)
    _, err = io.Copy(w, fr)
    if err != nil {
        log.Fatalf("faield to gzip: %v", err)
    }
}

檢視執行時間:

$ go build -o pgzip_demo
$ time ./pgzip_demo
./pgzip_demo  0.07s user 0.08s system 240% cpu 0.064 total

可見,使用 pgzip 壓縮同樣 100MB 大小的檔案,使用 4 核 CPU 時壓縮耗時有幾十倍(1.86s -> 0.07s)的縮短!

總結

pgzip 實現了分塊並行的 gzip 壓縮能力,極大提升了壓縮速率,能夠充分利用多核 CPU 的計算資源。當然,pgzip 提升壓縮速率的同時也會消耗更多的計算資源,能夠達到的壓縮比也會比原生 gzip 略低。

pgzip 非常適用於大檔案壓縮的場景,例如提升構建產物的打包速率、優化資料備份時效等,快來試試吧!

參考資料


歡迎加入 GOLANG 中國社群:https://gocn.vip

更多原創文章乾貨分享,請關注公眾號
  • 高效能 gzip 壓縮工具 pgzip
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章