圧縮コマンドのススメ

圧縮系コマンドの試験

弊社の長谷川の記事[圧縮形式検証(MongoDBのDumpがでかい!)]を見て「圧縮コマンドについてもっと知りたい!」と思い、居ても立っても居られなくなりました。さあshimichan、検証をしましょう。

ローカルに置くにしても、GCSへ上げるにしても、データサイズは極力小さくしておきたいものです。

人気コンテンツにもなるとバックアップデータが巨大になり、GCSなんかへデイリーでそのままバックアップしようものなら加速度的に料金もバカにできない大きさに膨れ上がります。

そんな訳でリソースの使用時間を極力減らしつつ(圧縮速度上げつつ)、圧縮効率も上げれないかな(もっと小さくできないかな)ー、ついでにいざという時のために伸張速度も早いと良いなー、という感じの視点で調べてみます。特に今回は大きなファイルを。

環境など諸々

今回は tar コマンドのドキュメントに載っている圧縮ツールの試験をしてみました。(LINK)

バージョン

バージョンについては、基本gceの centos7 のイメージにデフォルトで入ってる物を使用。

入ってないのは yum でササっと入れました。

拡張子 コマンド バージョン default(GCE)
.gz gzip 1.5 1.5
.bz2 bzip2 1.0.6(yum) none
.lz lzip 1.19(yum) none
.lzma lzma 5.2.2(yum) none
.lzo lzop 1.03(yum) none
.xz xz 5.2.2 5.2.2

環境

os : CentOS Linux release 7.5.1804 (Core)

カーネル : 3.10.0-862.14.4.el7.x86_64

ディスク:xfs でマウントしたHDD

使用するデータ : mongodumpで取得したそれぞれ1G, 5G, 10Gのバイナリデータ

1g_sample_dump 5g_sample_dump 10g_sample_dump
size 1048136 byte 5154744 byte 10475816 byte

実施方法

  • time コマンドを使い、各データを3回圧縮・伸張を行って real の平均時間を出す。
  • 今回はデフォルトと –fast オプションの二つをそれぞれ実施。(lzma, xzについては非推奨なので、一つ上の -1 のcompression levelで実施しています)

  • 1G, 5G, 10Gのmongoのdumpデータをそれぞれ圧縮・伸張する

  • 圧縮速度・圧縮率・伸張速度の3つの観点で見てみます。

  • デフォルトがマルチコア対応のものは、条件を合わせるため全てシングルスレッドで試験

※ lzop については、 -U で他と同様、圧縮後に元ファイルを削除するオプションをつけて実施

※ bizipの オプションは厳密にはcompression levelではないけど、一応。。。

ひとまず実施結果

結果どーん。

圧縮速度

コマンド 1g_sample_dump 5g_sample_dump 10g_sample_dump
gzip (-6) 0h0m31.86s 0h2m17.46s 0h4m35.21s
gzip (–fast) 0h0m11.86s 0h0m58.9s 0h1m59.36s
bzip2 (-9) 0h1m34.48s 0h7m45.12s 0h15m43.78s
bzip2 (–fast) 0h1m23.61s 0h6m46.22s 0h13m43.93s
lzip (-6) 0h12m12.72s 1h65m32.42s 2h134m54.43s
lzip (–fast) 0h0m23.21s 0h1m51.59s 0h3m47.4s
lzma (-T 1 -6) 0h11m53.49s 1h63m27.59s 2h133m21.53s
lzma (-T 1 -1) 0h0m42.05s 0h3m24.48s 0h6m49.97s
lzop (-3 -U) 0h0m9.59s 0h0m50.05s 0h1m40.39s
lzop (–fast -U) 0h0m9.04s 0h5m0.57s 0h13m34.83s
xz (-T 1 -6) 0h12m24s 1h65m40.22s 2h133m32.43s
xz (-T 1 -1) 0h0m43.81s 0h3m30.86s 0h7m12.14s

伸張速度

コマンド 1g_sample_dump 5g_sample_dump 10g_sample_dump
gzip (-6) 0h0m7.57s 0h0m40.36s 0h1m27.05s
gzip (–fast) 0h0m7.95s 0h0m44.08s 0h1m31.25s
bzip2 (-9) 0h0m33.37s 0h2m31.42s 0h5m0.2s
bzip2 (–fast) 0h0m20.21s 0h1m37.74s 0h6m49.16s
lzip (-6) 0h0m13.17s 0h1m1s 0h2m2.26s
lzip (–fast) 0h0m13.34s 0h1m3.17s 0h2m9.12s
lzma (-T 1 -6) 0h0m10.78s 0h0m37.73s 0h1m39.11s
lzma (-T 1 -1) 0h0m9.19s 0h0m43.81s 0h1m30.32s
lzop (-3 -U) 0h0m4.97s 0h0m45.35s 0h1m37.39s
lzop (–fast -U) 0h0m4.83s 0h4m17.91s 0h13m31.61s
xz (-T 1 -6) 0h0m12.21s 0h0m57.82s 0h1m52.18s
xz (-T 1 -1) 0h0m10.57s 0h0m50.68s 0h1m43.31s

圧縮率

コマンド 1g_sample_dump 5g_sample_dump 10g_sample_dump
gzip (-6) 135,708 byte(12.95%) 633,740 byte(12.29%) 1,291,588 byte(12.33%)
gzip (–fast) 152,584 byte(14.56%) 702,816 byte(13.63%) 1,419,108 byte(13.55%)
bzip2 (-9) 98,488 byte(9.40%) 492,268 byte(9.55%) 1,000,812 byte(9.55%)
bzip2 (–fast) 102,032 byte(9.73%) 491,240 byte(9.53%) 984,252 byte(9.40%)
lzip (-6) 64,024 byte(6.11%) 311,504 byte(6.06%) 635,196 byte(6.06%)
lzip (–fast) 87,668 byte(8.36%) 410,000 byte(8.13%) 851,788 byte(8.15%)
lzma (-T 1 -6) 63,776 byte(6.08%) 313,524 byte(6.08%) 637,204 byte(6.08%)
lzma (-T 1 -1) 80,380 byte(7.67%) 365,428 byte(7.22%) 756,620 byte(7.22%)
lzop (-3 -U) 233,656 byte(22.29%) 1,052,644 byte(20.07%) 2,102,668 byte(20.07%)
lzop (–fast -U) 233,852 byte(22.31%) 1,053,744 byte(20.09%) 2,104,680 byte(20.95%)
xz (-T 1 -6) 63,784 byte(6.09%) 63,784 byte(6.08%) 63,784 byte(6.08%)
xz (-T 1 -1) 80,392 byte(7.67%) 80,392 byte(7.09%) 80,392 byte(7.22%)

順位

ちょっと見辛いので順位を見てみます

1Gの圧縮速度 5Gの圧縮速度 10Gの圧縮速度 1Gの伸張速度 5Gの伸張速度 10Gの伸張速度 平均圧縮率
1位 lzop (–fast -U) lzop (-3 -U) lzop (-3 -U) lzop (–fast -U) lzma (-T 1 -6) gzip (-6) lzip (-6)
2位 lzop (-3 -U) gzip (–fast) gzip (–fast) lzop (-3 -U) gzip (-6) lzma (-T 1 -1) lzma (-T 1 -6)
3位 gzip (–fast) lzip (–fast) lzip (–fast) gzip (-6) lzma (-T 1 -1) gzip (–fast) xz (-T 1 -6)
4位 lzip (–fast) gzip (-6) gzip (-6) gzip (–fast) gzip (–fast) lzop (-3 -U) lzma (-T 1 -1)
5位 gzip (-6) lzma (-T 1 -1) lzma (-T 1 -1) lzma (-T 1 -1) lzop (-3 -U) lzma (-T 1 -6) xz (-T 1 -1)
6位 lzma (-T 1 -1) xz (-T 1 -1) xz (-T 1 -1) xz (-T 1 -1) xz (-T 1 -1) xz (-T 1 -1) lzip (–fast)
7位 xz (-T 1 -1) lzop (–fast -U) lzop (–fast -U) lzma (-T 1 -6) xz (-T 1 -6) xz (-T 1 -6) bzip2 (-9)
8位 bzip2 (–fast) bzip2 (–fast) bzip2 (–fast) xz (-T 1 -6) lzip (-6) lzip (-6) bzip2 (–fast)
9位 bzip2 (-9) bzip2 (-9) bzip2 (-9) lzip (-6) lzip (–fast) lzip (–fast) gzip (-6)
10位 lzma (-T 1 -6) lzma (-T 1 -6) lzma (-T 1 -6) lzip (–fast) bzip2 (–fast) bzip2 (-9) gzip (–fast)
11位 lzip (-6) lzip (-6) xz (-T 1 -6) bzip2 (–fast) bzip2 (-9) bzip2 (–fast) lzop (-3 -U)
12位 xz (-T 1 -6) xz (-T 1 -6) lzip (-6) bzip2 (-9) lzop (–fast -U) lzop (–fast -U) lzop (–fast -U)

さて検証

色々データを出してみたところで、色々みてみます。

圧縮速度

lzopについてはデータが大きくなると –fast よりデフォルトで動かす方が倍早いという結果に。

おなじみの gzip は圧縮率(12%〜15%)に関しては、相対的に順位こそ下ですが、全体的な速度としては5位以内に入っています。 –fast オプションをつけるとしっかり早くなってくれるので流石の安定感といったところです。

lziplzma はオプション無しだと使うのはなかなかしんどいかも。。。

伸張速度

全体的に伸張速度はそこまで気にする差ではないですね。

ただ、 bzip デフォルト(-6) & --fastlzop --fast はデータが大きくなればなるほど大きくスピードが落ちている。

また、 lzop の方ですが、データが大きくなると –fast オプションの方がデフォルトのcompression levelより遅いという結果に。デフォルトの圧縮の速さはすごく見えますが gzip –fast とほぼ同じ。圧縮率が20%を超えているので、無理にlzopを使う必要はさなさそう。

圧縮率

しっかりと時間をかけてやれば、デフォルトの lzip , lzma , xz のLZMAアルゴリズムを使ったコマンドが同列の1位(差分±0.01)。ただ、オプション無しのこの3強は、圧縮速度がぶっちぎりで遅いのが難点(どれも10G圧縮に2時間超え)。あまりに大きいファイルに関しては、compress levelのオプション指定無しに運用するのはちょっと辛いかもですね。

ちなみに圧縮率と順位を並べてみるとこんな感じ。

順位 コマンド 平均圧縮率
1位 lzip (-6) 6.07%
2位 lzma (-T 1 -6) 6.08%
3位 xz (-T 1 -6) 6.08%
4位 lzma (-T 1 -1) 7.33%
5位 xz (-T 1 -1) 7.33%
6位 lzip (–fast) 8.15%
7位 bzip2 (-9) 9.50%
8位 bzip2 (–fast) 9.55%
9位 gzip (-6) 12.52%
10位 gzip (–fast) 13.91%
11位 lzop (-3 -U) 20.93%
12位 lzop (–fast -U) 20.95%

いったん速度を置いておいて、 gzip を基準に見てみると、どれも優秀な印象を受けます

LZMA系のコマンドはどれもgzipの半分ですね。 xzlzip はたまにアップデートを続けているようです。

個人的な評価

今回はあくまでも “大きなファイルに対してのパフォーマンス” の試験です。

そして個人的な見解ですが、

まず、やっぱり gzip スゲー。

圧縮率でこそ今回試験したコマンドの中では下位の順位ですが、それに勝る圧縮・伸張の速さと安定感。

gzip–fast オプションはそこまで圧縮率に影響がない(差分2%未満)にも関わらず 、圧縮速度が約2〜3倍となったので、速度に困ったらとりあえず –fast オプションをつければいいかな、といったところでしょうか。

先ほども触れましたが、 lzop は圧縮速度こそぶっちぎりの一位ですが、圧縮率がどうしても悪く見えてしまいます。伸張速度の観点でも触れましたが、オプションをつければ逆にパフォーマンスが落ちるので、大きなファイルには動作が安定していない印象。よほど圧縮速度にこだわらない限りはインストールしてまで使う必要はないと思います。( lzop を抜きに見れば gzip が圧縮・伸張ともにダントツ一位。。。)

bzip も全体的に目立って良い訳ではないので、今回の観点以外でメリットを見つけれない限りは大きなファイルに対して使う機会は少なそう。

そこで gzip の次に成績が良かったのは lzip --fast 。圧縮・伸張は gzip --fast の倍時間がかかります(それでも十分早い!)が、圧縮率は gzip --fast の約40%圧縮効率を高めてくれます( デフォルトの gzip と比べると 35%)。 圧縮率を優先するなら lzip --fast かな〜といったところ。デフォルト使うには圧縮に時間がかかり過ぎ( gziplzip –fast に比べると約30〜35倍、)なので、compress levelの指定無しには大きなファイルを扱うのはちょっと厳しい。1core丸々を圧縮のためだけに使うのは。。。

ただ、今回条件を揃えるために lzmaxz はスレッド数を -T 1 に指定して実行していたので、ちゃんとしたポテンシャルを発揮できてはいないです。 どの compress levelが一番良いかは別途検証する必要がありますね。

まとめ

大きなファイルに対して。

1スレッドで動かす場合の基本的な運用は gzip で十分でしょうか。

そして、 gzip 以外の選択肢としては大まかにこんなパターンで使い分けする方が良いのかな〜と。

1 長時間 cpu の負荷が高騰する (もう少し速度欲しいなって)時

gzip --fast オプションをつけて、圧縮時間を短縮。とりあえず半分ぐらいにはなる。

2 圧縮率をあげたい

lizip , xz , lzma のいずれかお好みの compress level オプション指定で圧縮。(丁度いいさじ加減探す必要有)

3 とにかく gzip 以上の圧縮率で、可能な限り早く!

lizip , xz , lzma--fast オプションをつける

小さいファイルに対しての圧縮や、マルチコアを使った処理など色々検証すべき点はありますが、それはまたの機会に比べてみたいと思います。

ではでは。