Gzip なしで Tar アーカイブを作成するとどれくらい速くなりますか?
GzipとTarについて

LinuxとBSDでは、gzipというプログラムをよく使っているようですが、これはtarという別のプログラムと組み合わせて使われることが多いようです。Tape ARchiveにちなんで名付けられたtarは、ファイルとフォルダ(「ディレクトリ」)を、もともと磁気テープへのアーカイブ用に設計された形式にコピーするプログラムです。しかし、tarアーカイブはテープ以外にも多くのファイルシステムに保存できます。tarアーカイブは、通常のハードドライブ、ソリッドステートドライブ、NVMeドライブなど、さまざまな場所に保存できます。
アーカイブを作成する際、多くの場合、アーカイブのサイズを最小限に抑えたいと考えます。そこでgzipが役立ちます。gzipはアーカイブのサイズを縮小し、ストレージ容量を節約します。gzipで圧縮されたtarアーカイブは、後ほど「解凍」できます。解凍すると、tarアーカイブは元のサイズに戻ります。解凍中に、tarプログラムを再び使用してアーカイブを「展開」または「アンター」できます。展開によって、アーカイブされた元のファイルは、アーカイブ作成時と全く同じ状態に戻ります。
長期保存用のアーカイブに加え、多くの人が短期的なバックアップにtarやgzipをよく利用しています。例えば、私のサーバーDarkstarでは、多くのプログラムをコンパイルしてインストールしています。コンパイル前には、tarを使ってコンパイルとインストール前の状態を短期的にバックアップしています。
コンパイルする3つの理由
まず、コンパイルすることで、プログラムの最新のソースコードが得られます。次に、数回コンパイルを行えば、ディストリビューションのパッケージマネージャーを使って古いバージョンをインストールする方法を考えるよりも、最新のソースコードからプログラムをコンパイルする方が簡単になります。さらに、自分でコンパイルすることで、プログラムのソースコードがすぐに利用できるようになります。
Darkstarでコンパイルするプログラムは通常/usr/localに保存します。新しいプログラムをusr/localに配置する前に、(Darkstarの定期的なバックアップに加えて)新しいソフトウェアを追加する直前の/usr/localのアーカイブを作成しておくようにしています。便利な/usr/localアーカイブがあれば、新規インストール中に何か問題が発生しても簡単に元に戻すことができます。
コンパイル前のバックアップの作成に時間がかかりすぎる
最近、/usr/local にソフトウェアが追加されたため、コンパイル前のアーカイブの作成に約 30 分と長い時間がかかるようになりました。
最近、 top(1)コマンドを使ってアーカイブの作成を観察しました。すると、アーカイブ作成中ずっとgzipがCPUを100%使用していると報告されていました。
Gzip を使わずにプレーン Tar アーカイブを作成すると、どれくらい高速化され、サイズも大きくなりますか?
gzip を使わない場合、プリコンパイルアーカイブの作成にかかる時間全体がどれほど変わるのか気になりました。また、アーカイブのサイズもどれくらい大きくなるのか気になりました。以下に、作成時間の差が驚くほど大きいことを発見したデータと分析結果を示します。アーカイブサイズもかなりの違いがありますが、作成時間の差ほどではありません。
作成時間データ
コンパイル前のアーカイブを2回実行しました。1回はgzipあり、もう1回はgzipなしで実行しました。両方のテストの行番号付きトランスクリプトを作成しました。
000023 root@darkstar:/usr# time tar cvzf local-revert.tgz local
000024 local/
[ . . . ]
401625 local/include/gforth/0.7.3/config.h
401626
401627 real 28m11.063s
401628 user 27m1.436s
401629 sys 1m21.425s
401630 root@darkstar:/usr# time tar cvf local-revert.tar local
401631 local/
[ . . . ]
803232 local/include/gforth/0.7.3/config.h
803233
803234 real 1m14.494s
803235 user 0m4.409s
803236 sys 0m46.376s
803237 root@darkstar:/usr#
このStack Overflowの投稿では、 time(1)コマンドで報告される実時間、ユーザー時間、システム時間の違いについて説明しています。「実時間」は壁時計の時間なので、コマンドの実行にかかった時間を示します。
Gzip は 22 倍の時間がかかりました。
ここで、gzipを使用したアーカイブの作成には約28分かかったことがわかります。gzipを使用しないアーカイブの作成にはわずか1.25分しかかかりませんでした。gzipで圧縮したアーカイブの作成には、解凍したアーカイブの22倍の時間がかかりました。
アーカイブサイズデータ
それではアーカイブのサイズを確認しましょう。
root@darkstar:/usr# ls -lh local-revert.t*
-rw-r--r-- 1 root root 22G Oct 4 05:22 local-revert.tar
-rw-r--r-- 1 root root 10G Oct 4 05:20 local-revert.tgz
root@darkstar:/usr#
gzip 圧縮されたアーカイブは 10 ギガバイト、圧縮されていないプレーンな tar アーカイブは 22 ギガバイトです。
Gzip の圧縮率は 55% でした。
圧縮されたアーカイブは55%圧縮されました。かなりの圧縮率ですね!
結論
Darkstarにはディスク容量がたっぷりあります。ですから、アーカイブのサイズは2倍でも作成速度は22倍になるのが最善の選択かもしれません。今後は、コンパイル前に/usr/localをバックアップする際に圧縮を一切行わず、revertを有効にするようにします。これでもう30分も待つ必要がなくなります!
追加の考察
作成時間とアーカイブサイズは、対象となるファイルの種類によって異なることが予想されます。例えば、Darkstarの/usr/localにあるファイルとは異なり、多くの画像ファイル形式は既に圧縮されているため、追加の圧縮を行ってもサイズはそれほど小さくなりません。
この記事を準備していた時に、 pigzについて知りました。pigz (発音は「ピグジー」)は、マルチコアプロセッサのメリットを活かせるgzipの実装です。もしかしたら、pigzは近いうちにDarkstarの/usr/localに新しく加わるかもしれません。
圧縮を高速化するもう一つの方法は、gzip以外の圧縮プログラムを使うことです。bzip2やxzなど、よく使われる圧縮プログラムは数多くあります。これらの圧縮プログラムは、tarの-Iオプションで呼び出すことができます。
もちろん、tarの-Iオプションで圧縮プログラムを変更することと、tar自体を並列処理させることは別問題です。tarの並列処理に関するStack Exchangeの投稿がこちらにあります。試してみたいと思います。
最後に、ソースコードとコンパイル済みのプログラムを別々に入手する場合とは異なり、自分でコンパイルしたソースコードが実際に実行するプログラムのソースコードであることは明白です。しかし、1984年にケン・トンプソンは、自分でコンパイルしたプログラムが期待とは 大きく異なる場合があることを認識していました。