檔案壓縮順序造成壓縮率的差異

Hacker News Daily 上看到「Why are tar.xz files 15x smaller when using Python's tar library compared to macOS tar?」這篇,作者問了為什麼他用 Pythontarfile 壓出來比起用 tar 壓出來小了 15 倍,檔案都是 JSON 檔壓成 XZ 格式:

I'm compressing ~1.3 GB folders each filled with 1440 JSON files and find that there's a 15-fold difference between using the tar command on macOS or Raspbian 10 (Buster) and using Python's built-in tarfile library.

看到 1440 個檔案應該會有直覺是一分鐘一個檔案,跑一天的量...

隔天他把原因找出來了,在裝了 GNU Tar 並且加上 --sort='name' 參數後,壓出來的大小就跟 Python 的 tarfile 差不多了:

Ok, I think I found the issue: BSD tar and GNU tar without any sort options put the files in the archive in an undefined order.

After installing GNU tar on my Mac with:

brew install gnu-tar

And then tarring the same folder, but with the --sort option:

gtar --sort='name' -cJf zsh-archive-sorted.tar.xz /Users/user/Desktop/temp/tar/2021-03-11

I get a .tar.xz archive of 1.5 MB, equal to the archive created by the Python library.

底層的原因是檔名與檔案內容有正相關的相似度 (因為裡面都是 sensor 資料),依照檔名排序壓縮就等於把類似的 JSON 檔案放在一起壓,使得 xz 可以利用這點急遽拉高壓縮率:

My JSON files contain measurements from hundreds of sensors. Every minute I read out all sensors, but only a few of these sensors have a different value from minute to minute.

By sorting the files by name (which has the creation unixtime at the beginning of it), two subsequent files have very little different characters between them. Apparently this is very favourable for the compression efficiency.

遇到類似的情境可以當作 tuning 的一種,測試看看會不會變小很多...

Arch Linux 決定把套件壓縮演算法從 xz 換成 Zstandard

看到 Arch Linux 的公告,他們決定把套件的壓縮演算法從 xz 換成 Zstandard:「Now using Zstandard instead of xz for package compression」。

從 xz 換成 Zstandard 主要的原因在於不用犧牲太多空間 (多 0.8% 的空間),但解壓縮的速度可以大幅提昇 (提昇 13 倍):

zstd and xz trade blows in their compression ratio. Recompressing all packages to zstd with our options yields a total ~0.8% increase in package size on all of our packages combined, but the decompression time for all packages saw a ~1300% speedup.

看起來是不斷發酵... 在幾個月前隔壁棚的 Fedora 先換過去了,計畫在「Changes/Switch RPMs to zstd compression」這邊可以翻到,而 issue tracking system 上的記錄可以參考「Issue #350: F31 System-Wide Change: Switch RPMs to zstd compression - release-notes - Pagure.io」。

看起來會是趨勢了...

Amazon Redshift 的新功能 (BZIP2)

Amazon Redshift 也推出了好幾個新功能,不過有個有點奇怪的壓縮格式 bzip2 出現了:「Amazon Redshift announces tag-based permissions, default access privileges, and BZIP2 compression format」。

BZIP2 data format: The COPY command now accepts data in BZIP2 compression format, in addition to GZIP and LZOP formats, when loading data into Amazon Redshift. Refer to Data Format Parameters for more details.

既然出了 bzip2,為什麼不一起出個效率與壓縮率都更好的 xz?但不管怎樣,總是多了一個壓縮率再更高一點的選擇... @_@

Linux Kernel 將不提供 bzip2 格式了...

kernel.org 上看到 Linux Kernel 將不提更 bzip2 格式的原始程式包了:「Happy new year and good-bye bzip2」。

之後只會提供 .tar.gz (為了廣泛的可用性) 與 .tar.xz (為了大小,降低傳輸量)。xz 壓出來小不少,也愈來愈多的單位在用了...

bzip2 也一陣子沒更新了,上次更新是 1.0.6,是為了安全性更新 CVE-2010-0405,而 1.0.5 也是安全性更新,真正有新版本是 1.0.4 (2006 年 12 月)。

算是功成身退了?

xz (LZMA) 的壓縮率

之前 BBS 備份都是用 gzip 加上 openssl 加密後丟上 Amazon S3,檔案大約 1GB 左右,曾經用過 bzip2,大約是 900MB,但多出來的壓縮時間與換到的空間讓人沒辦法接受...

前陣子在測 7z 格式時才發現 xz 的壓縮率高的嚇人... 當然,壓縮的時間會更久,但可以壓到少於 500MB,這對於丟上 S3 的成本就少了很多...

這是壓縮的結果:

xz -1xz -2 的速度都非常快,跟 gzip -9 以及 bzip2 -9 差不多。沒意外的話 (像是軟體專利),應該是未來的趨勢了...