.tar.gz
アーカイブの問題は、アーカイブのコンテンツを一覧表示しようとすると、コンピュータが実際に圧縮解除するため、ファイルが大きい場合に非常に長い時間がかかることです。
.7z
、.rar
、.Zip
などの他のファイル形式には、この問題はありません。それらの内容をリストすることはほんの一瞬です。
私の素朴な意見では、これは.tar.gz
アーカイブ形式の大きな欠点です。
だから私は実際に2つの質問があります:
.tar.gz
をそれほど多く使用するのですか?ここにはトレードオフがあることを理解することが重要です。
tar
はテープアーカイバを意味します。テープでは、ほとんどの場合、順次読み取りと書き込みを行います。テープは現在ほとんど使用されていませんが、tar
は、データをストリームとして読み書きする機能のために引き続き使用されています。
できるよ:
tar cf - files | gzip | ssh Host 'cd dest && gunzip | tar xf -'
Zip
などではできません。
Zip
アーカイブの内容を、シーク可能なファイルにローカルに保存せずにリストすることもできません。次のように考えます:
curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.Zip | unzip -l /dev/stdin
動作しません。
コンテンツをすばやく読み取るには、Zip
などでインデックスを作成する必要があります。そのインデックスは、ファイルの最初(ストリームではなく通常のファイルにのみ書き込むことができます)または最後に保存できます。つまり、アーカイバは最後に印刷する前にすべてのアーカイブメンバーを覚えておく必要があります。また、切り捨てられたアーカイブは復元できない可能性があります。
これは、アーカイブメンバーを個別に圧縮する必要があることも意味します。これは、特に小さなファイルが多い場合、圧縮率がはるかに低くなることを意味します。
Zip
のような形式のもう1つの欠点は、アーカイブが圧縮にリンクされているため、圧縮アルゴリズムを選択できないことです。 tar
アーカイブがcompress
(tar.Z
)、次にgzip
、bzip2
、xz
のいずれで圧縮されていたかをご覧ください。新しいより高性能な圧縮アルゴリズムが考案されました。暗号化についても同様です。今日、Zip
の暗号化を信頼するのは誰ですか?
さて、tar.gz
アーカイブの問題は、それらを解凍するために必要なものではありません。多くの場合、圧縮解除はディスクからの読み取りよりも高速です(メモリにキャッシュされていない場合、大きなtgzアーカイブの内容をリストする方が、圧縮されていない同じものをリストするよりも速いでしょう)が、アーカイブ全体を読み取る必要があります。
インデックスをすばやく読み取れないことは、実際には問題ではありません。アーカイブのテーブルコンテンツを頻繁に読み取る必要がある場合は、そのリストを別のファイルに保存してください。たとえば、作成時に次のことができます。
tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz
IMOのさらに大きな問題は、アーカイブのシーケンシャルな側面が原因で、アーカイブの先頭セクション全体を読み取らずに個々のファイルを抽出できないことです。 IOW、アーカイブ内でランダムな読み取りを行うことはできません。
さて、シーク可能なファイルについては、そのようにする必要はありません。
tar
アーカイブをgzip
で圧縮すると、全体として圧縮されます。圧縮アルゴリズムは、最初に表示されたデータを使用して圧縮するため、最初から圧縮を解除する必要があります。
ただし、xz
形式は、個別の個別のチャンク(効率的に圧縮するのに十分な大きさ)でデータを圧縮するように構成できます。つまり、シーク可能なファイルについて、それらの圧縮チャンクの最後にインデックスを保持している限り、アクセスできます。ランダムに(少なくともチャンクで)非圧縮データ。
pixz
(パラレルxz
)は、tar
アーカイブを圧縮するときにその機能を使用して、xz
ファイルの末尾にアーカイブの各メンバーの先頭のインデックスも追加します。
したがって、シーク可能なファイルの場合、pixz
で圧縮されていれば、tarアーカイブの内容のリストを(メタデータなしで)即座に取得できるだけでなく、
pixz -l file.tar.xz
ただし、アーカイブ全体を読み取らずに、個々の要素を抽出することもできます。
pixz -x archive/member.txt < file.tar.xz | tar xpf -
さて、なぜ7z
やZip
のようなものがUnixでめったに使用されないのかについては、ほとんどがUnixファイルをアーカイブできないためです。これらは他のオペレーティングシステム用に設計されています。これらを使用してデータを忠実にバックアップすることはできません。所有者(IDと名前)、許可などのメタデータを保存できません。シンボリックリンク、デバイス、FIFOなどを保存できません。ハードリンクに関する情報や、拡張属性やACLなどの他のメタデータ情報を保存できません。
それらの一部は、任意の名前のメンバーを保存することさえできません(一部は、バックスラッシュ、改行、コロン、または非ASCIIファイル名で窒息します)(一部のtar
形式にも制限があります)。
明らかでない場合は、tgz
またはtar.bz2
、tar.xz
...アーカイブを次のように使用しません。
unxz file.tar.xz tar tvf file.tar xz file.tar
圧縮されていない.tar
ファイルがファイルシステム上にある場合は、何か問題が発生しています。
これらのxz
/bzip2
/gzip
がストリームコンプレッサであることの要点は、次のようにパイプラインでオンザフライで使用できることです。
unxz < file.tar.xz | tar tvf -
最近のtar
の実装は、unxz
/gunzip
/bzip2
を自分で呼び出す方法を知っているので、
tar tvf file.tar.xz
一般的にも機能します(データをその場で解凍し、圧縮されていないバージョンのアーカイブをディスクに保存しません)。
これは、さまざまな形式で圧縮されたLinuxカーネルソースツリーです。
$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.Zip
97038336 linux-4.6.7z
89468928 linux-4.6.tar.xz
まず、上記のように、7zとZipはわずかに異なります。これらはそこに少数のシンボリックリンクを格納できず、ほとんどのメタデータが欠落しているためです。
次に、システムキャッシュをフラッシュした後、コンテンツをリストするタイミングをいくつか示します。
$ echo 3 | Sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null 0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null 8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.Zip > /dev/null
unzip -v linux-4.6.Zip > /dev/null 0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null 0.51s user 0.15s system 89% cpu 0.739 total
この7歳のPCでも、tar.xz
ファイルの一覧表示は.tar
のファイル一覧よりも速いことに気付くでしょう。ディスクから追加のメガバイトを読み取るのは、小さいファイルを読み込んで解凍するよりも時間がかかるためです。
次に、7zまたはZipを使用してアーカイブを一覧表示する方が高速ですが、前述のとおり問題ありません。ファイルリストをアーカイブと一緒に保存することで簡単に回避できます。
$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null 0.05s user 0.00s system 99% cpu 0.051 total
キャッシュを削除した後でも、7zまたはZipよりも高速です。また、アーカイブとそのインデックスの累積サイズがZipまたは7zアーカイブよりも小さいことにも気づくでしょう。
または、pixz
インデックス形式を使用します。
$ xzcat linux-4.6.tar.xz | pixz -9 > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | Sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null 0.04s user 0.01s system 57% cpu 0.087 total
ここで、アーカイブの個々の要素を抽出するために、tarアーカイブの最悪のシナリオは、最後の要素にアクセスするときです。
$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root 5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c 7.27s user 1.13s system 115% cpu 7.279 total
wc 0.00s user 0.00s system 0% cpu 7.279 total
アーカイブ全体を読み取る(そして圧縮解除する)必要があるため、これはかなり悪いことです。と比べて:
$ time unzip -p linux-4.6.Zip linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
unzip -p linux-4.6.Zip linux-4.6/virt/lib/irqbypass.c 0.02s user 0.01s system 19% cpu 0.119 total
wc 0.00s user 0.00s system 1% cpu 0.119 total
私のバージョンの7zはランダムアクセスを実行できないようなので、tar.xz
よりもさらに悪いようです。
$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
257 638 5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null 7.28s user 0.12s system 89% cpu 8.300 total
wc 0.00s user 0.00s system 0% cpu 8.299 total
これで、pixz
を以前のものから生成したので、
$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz 1.37s user 0.06s system 84% cpu 1.687 total
tar xOf - 0.00s user 0.01s system 0% cpu 1.693 total
wc 0.00s user 0.00s system 0% cpu 1.688 total
アーカイブには大きなブロックがほとんど含まれていないため、高速ですが比較的低速です。
$ pixz -tl linux-4.6.tar.pixz
17648865 / 134217728
15407945 / 134217728
18275381 / 134217728
19674475 / 134217728
18493914 / 129333248
336945 / 2958887
したがって、pixz
は、最大19MBのデータのチャンク(最大1つ)を読み取って圧縮解除する必要があります。
アーカイブを小さくすることでランダムアクセスを高速化することができます(そしてディスク容量を少し犠牲にします):
$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2 0.17s user 0.02s system 98% cpu 0.189 total
tar xOf - 0.00s user 0.00s system 1% cpu 0.188 total
wc 0.00s user 0.00s system 0% cpu 0.187 total