Saya baru saja melakukan percobaan kecil di mana saya membuat arsip tar dengan file duplikat untuk melihat apakah itu akan dikompresi, saya kagum, ternyata tidak! Detail mengikuti (hasil indentasi untuk kesenangan membaca):
$ dd if=/dev/urandom bs=1M count=1 of=a
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.114354 s, 9.2 MB/s
$ cp a b
$ ln a c
$ ll
total 3072
-rw-r--r-- 2 guido guido 1048576 Sep 24 15:51 a
-rw-r--r-- 1 guido guido 1048576 Sep 24 15:51 b
-rw-r--r-- 2 guido guido 1048576 Sep 24 15:51 c
$ tar -c * -f test.tar
$ ls -l test.tar
-rw-r--r-- 1 guido guido 2109440 Sep 24 15:51 test.tar
$ gzip test.tar
$ ls -l test.tar.gz
-rw-r--r-- 1 guido guido 2097921 Sep 24 15:51 test.tar.gz
$
Pertama saya membuat file data acak 1MiB (a). Kemudian saya menyalinnya ke file b dan juga menghubungkannya dengan c. Saat membuat tarball, tar tampaknya menyadari hardlink, karena tarball hanya ~ 2MiB dan bukan ~ 3Mib.
Sekarang saya berharap gzip mengurangi ukuran tarball menjadi ~ 1MiB karena a dan b adalah duplikat, dan harus ada 1MiB data kontinu diulang di dalam tarball, namun ini tidak terjadi.
Kenapa ini? Dan bagaimana saya bisa mengompres tarball secara efisien dalam kasus ini?
sumber
xz -9 -M 95%
, atau bahkanxz -M 95% --lzma2=preset=9,dict=1610612736
. Itu tidak akan cepat, tetapi duplikat Anda tidak mungkin dibiarkan dalam hasil.Nicole Hamilton dengan benar mencatat bahwa
gzip
tidak akan menemukan data duplikat yang jauh karena ukuran kamusnya yang kecil.bzip2
mirip, karena terbatas pada memori 900 KB.Sebagai gantinya, cobalah:
Algoritma LZMA / LZMA2 (
xz
,7z
)Algoritma LZMA berada dalam keluarga yang sama dengan Deflate, tetapi menggunakan ukuran kamus yang jauh lebih besar (dapat disesuaikan; standarnya kira-kira 384 MB). The
xz
utilitas, yang harus diinstal secara default pada kebanyakan distro Linux terbaru, mirip dengangzip
dan menggunakan LZMA.Karena LZMA mendeteksi redundansi jarak yang lebih jauh, LZMA akan dapat menduplikasi data Anda di sini. Namun, ini lebih lambat dari Gzip.
Pilihan lain adalah 7-zip (
7z
, dalamp7zip
paket), yang merupakan pengarsipan (daripada kompresor aliran tunggal) yang menggunakan LZMA secara default (ditulis oleh penulis LZMA). Pengarsip 7-zip menjalankan deduplikasi sendiri di tingkat file (melihat file dengan ekstensi yang sama) ketika pengarsipan ke.7z
formatnya. Ini berarti bahwa jika Anda bersedia untuk menggantitar
dengan7z
, Anda mendapatkan file identik deduplicated. Namun, 7z tidak mempertahankan stempel waktu nanodetik, izin, atau xattr, sehingga mungkin tidak sesuai dengan kebutuhan Anda.lrzip
lrzip
adalah kompresor yang memproses data untuk menghilangkan redundansi jarak jauh sebelum memasukkannya ke algoritma konvensional seperti Gzip / Deflate, bzip2, lzop, atau LZMA. Untuk data sampel yang Anda berikan di sini, itu tidak perlu; ini berguna untuk saat input data lebih besar dari apa yang dapat ditampung dalam memori.Untuk jenis data ini (duplikat potongan yang tidak dapat dikompres), Anda harus menggunakan
lzop
kompresi (sangat cepat) denganlrzip
, karena tidak ada manfaatnya untuk berusaha lebih keras untuk mengompresi data yang benar-benar acak setelah data itu didupuplikasi.Bup dan Obnam
Karena Anda menandai cadangan pertanyaan , jika tujuan Anda di sini mencadangkan data, pertimbangkan untuk menggunakan program cadangan deduplicating seperti Bup atau Obnam .
sumber
Dalam hal cadangan, mungkin dengan sekumpulan file yang lebih kecil, satu trik yang mungkin bisa dilakukan untuk Anda adalah mengurutkan file dalam tar dengan ekstensi:
sumber
rev
itu (mengapa bahkan membalikkan dan kemudian mengurutkan?) Dan melihatsort
opsi "-r, --reverse" (meskipun saya tidak yakin mengapa Anda ingin membalikkan apa pun). Tapi saya pikirtar
pilihan Anda "-I
" tidak melakukan apa yang menurut Anda "-I, --use-compress-program PROG
" , Anda mungkin ingin "-T, --files-from FILE"| tar czf my_archive.tar.gz -I -
seharusnya| xargs tar Azf my_archive.tar.gz
rev
membalik urutan karakter di setiap baris, bukan urutan baris di aliran. Karena itu,sort
kelompokkan file dengan ekstensi mereka. Saya menduga-I -
seharusnya-T -
, yang menyediakan daftar file di stdin.rev
akan semacam mengatur dengan ekstensi, bukan berarti ada banyak ekstensi di linux pula. Saya membayangkan mengurutkan berdasarkan ukuran akan memiliki peluang lebih tinggi untuk menemukan dupgzip
tidak akan menemukan duplikat, bahkanxz
dengan ukuran kamus yang besar tidak akan menemukan. Apa yang dapat Anda lakukan adalah menggunakanmksquashfs
- ini memang akan menghemat ruang duplikat.Beberapa hasil pengujian cepat dengan
xz
danmksquashfs
dengan tiga file biner acak (64MB) yang keduanya sama:Mendirikan:
Squashfs:
xz:
sumber
Number of duplicate files found
di stdout.Pada sistem saya
lzma test.tar
menghasilkan file test.tar.lzma 106'3175 byte (1,1M)sumber
Sebagai tambahan untuk jawaban 'keong mekanik':
Bahkan xz (atau lzma) tidak akan menemukan duplikat jika ukuran file dari file tunggal terkompresi (atau, lebih tepatnya, jarak antara duplikat) melebihi ukuran kamus. xz (atau lzma) bahkan pada pengaturan tertinggi
-9e
hanya mencadangkan 64MB untuk ini.Untungnya Anda dapat menentukan ukuran kamus Anda sendiri dengan opsi
--lzma2=dict=256MB
(hanya--lzma1=dict=256MB
diizinkan saat menggunakan lzma alias ke perintah)Sayangnya, ketika mengesampingkan pengaturan dengan rantai kompresi khusus seperti yang diberikan dalam contoh di atas, nilai default untuk semua parameter lainnya tidak diatur ke level yang sama dengan -9e. Jadi kepadatan kompresi tidak setinggi untuk file tunggal.
sumber
gzip tanpa saklar baris perintah menggunakan algoritma kompresi yang serendah mungkin.
Coba gunakan:
Anda harus mendapatkan hasil yang lebih baik
sumber