Mengompresi banyak file besar yang serupa

18

Saya memiliki ratusan file besar yang serupa (masing-masing 30 megabyte) yang ingin saya kompres. Setiap pasangan file memiliki 99% data yang sama (perbedaan kurang dari 1%), jadi saya berharap tidak lebih dari 40-50 megabyte arsip.

File tunggal dapat dikompresi dari 30 MB ke 13-15 MB (dengan xz -1, gz -1, bzip2 -1), tetapi ketika mengompresi dua atau lebih file saya ingin memiliki arsip dengan ukuran 13-15MB + N*0.3MBdi mana N adalah jumlah file.

Saat menggunakan tar(untuk membuat arsip padat) dan xz -6(untuk menentukan kamus kompresi menjadi lebih besar dari satu file - Perbarui - ini tidak cukup! ), Saya masih memiliki arsip dengan ukuran N*13MB.

Saya pikir keduanya gzipdan bzip2tidak akan membantu saya karena mereka memiliki kamus kurang dari 1 MB, dan aliran tar saya memiliki pengulangan setiap 30 MB.

Bagaimana saya bisa mengarsipkan masalah saya di Linux modern menggunakan alat standar?

Apakah mungkin untuk menyetel xzkompres dengan cepat, tetapi gunakan kamus yang lebih besar dari 30-60 MB?

Pembaruan : Melakukan trik dengan tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. Tidak yakin tentang perlunya mf=hc4dan --memory=2Gopsi; tetapi dict=128Matur kamus menjadi cukup besar (lebih besar dari satu file), dan mode=fastbuat prosesnya lebih cepat dari -e.

osgx
sumber
Menjalankan xz -1 --memory=2Gtidak membantu, diuji pada 2 dan 4 file dari set.
osgx

Jawaban:

12

Dengan perincian Anda, saya berasumsi bahwa Anda telah memverifikasi bahwa file Anda benar-benar memiliki 99% data yang sama, dengan perbedaan 1% yang berdekatan (atau hampir bersebelahan).

Pertama, Anda harus menggunakan tar untuk membuat satu arsip dengan file Anda di dalamnya. Untuk tes, saya akan membuat .tar dengan 10 file, sehingga memiliki ukuran 300MB.

Kemudian, menggunakan xz, Anda harus mengaturnya sehingga kamus lebih besar dari ukuran satu file. Karena Anda tidak mengatakan jika Anda memiliki batasan memori, saya akan menggunakan xz -9. Tidak ada gunanya tidak menggunakan semua memori yang tersedia.

Saya juga menggunakan preset --extreme, untuk menguji apakah ada bedanya.

Ukuran kamus

Dalam satu dokumentasi yang saya miliki - situs - dikatakan bahwa ukuran kamus kira-kira sama dengan penggunaan memori dekompresor. Dan parameter -1 berarti dict dari 1MiB, -6 berarti 10 MiB (atau 8 MiB di bagian lain dari manual yang sama). Itu sebabnya Anda tidak mendapatkan keuntungan apa pun dengan menggabungkan file-file itu bersama-sama. Menggunakan -9 akan membuat pengurai (dan, jadi, kamus) menjadi 64 MIB, dan saya pikir itulah yang Anda inginkan.

Edit

Kemungkinan lain akan menggunakan kompresor lain. Saya akan pergi dengan 7zip, tetapi akan tar file-file itu terlebih dahulu dan kemudian 7zip mereka.

Bergantung pada konten file Anda, mungkin Anda bisa menggunakan 7zip dengan metode PPM-D (bukan LZMA atau LZMA2, itu adalah default dan sama dengan yang digunakan oleh xz)

Tidak bagus: Zip (dikt = 32kB), Bzip (dikt = 900 kB).

woliveirajr
sumber
Xz dan 7-Zip sama-sama menggunakan LZMA2 sehingga tidak akan ada manfaat di sana. PPMD dioptimalkan untuk ekstraksi entropi tingkat kompresi yang sangat lambat namun tinggi dari media yang sudah dikompresi (misalnya, MP3 dan video). Sangat tidak mungkin untuk menemukan kesamaan besar antara kedua file dan menyimpannya dalam kamus - tidak lebih dari LZMA2.
allquixotic
woliveirajr, bagaimana dengan menggunakan not -1atau -9preset, tetapi tentukan dict=64MBatau dict=128MBdan atur mode=fast?
osgx
Menggunakan dict = xxMB bukannya -1 atau -9 akan langsung ke intinya, tetapi karena saya tidak tahu bagaimana xz menetapkan parameter lain ketika Anda hanya menggunakan -9, saya tidak tahu apakah Anda tidak akan melewatkan sesuatu lain. Saya pikir Anda berada di arah yang benar, dan pengujian saja akan memberikan jawaban yang tepat.
woliveirajr
3
Dengan xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2Gsaya dapat mengkompres 250 file (7,5 GB) ke arsip tar.xz 18 MB.
osgx
@osgx :) itu cukup bagus. Jika tidak butuh terlalu banyak waktu (yaitu, itu sesuai kebutuhan Anda), masalah terpecahkan! :) Jadi Anda mendapatkan final_size = 13MB + x * 6kB, lebih atau kurang.
woliveirajr
9

Jika mereka benar-benar 99% mirip seperti yang Anda katakan, Anda harus dapat menggunakan bsdiff atau algoritma serupa untuk menghitung perbedaan antara file. Apakah perbedaannya kumulatif (yaitu, setiap file sedikit berbeda dari yang pertama), atau apakah perbedaan antara dua file hampir sama?

Jika tidak kumulatif, Anda harus dapat:

  • Ambil file sembarang sebagai "baseline"
  • Jalankan bsdiffmembandingkan file baseline ke setiap file tambahan
  • Simpan setiap diff sebagai file terpisah, di samping file baseline
  • Jalankan kompresor seperti xzmelintasi hasil (baseline + diff).

Hasilnya harus jauh lebih kecil daripada hanya xzseluruh arsip.

Anda kemudian dapat "menyusun kembali" file asli dengan "menerapkan" diff di atas baseline untuk mengeluarkan masing-masing file lainnya.

allquixotic
sumber
Tidak kumulatif. ("Setiap pasangan file memiliki 99% data yang sama ...")
osgx
1
Jika perbedaannya tidak kumulatif maka ini harus menjadi aplikasi bsdiffalgoritma yang baik. Cobalah.
allquixotic
Terima kasih atas jawaban Anda, tetapi saya sudah melakukan tugas dengan xz: tar c directory|xz --lzma2=dict=128M,mode=fastdan menghapus file input. Sebenarnya file input saya adalah teks, jadi saya bahkan dapat menggunakan diff bukan bsdiff(yang tidak diinstal pada PC saya).
osgx
5

Anda (saya) dapat menggunakan tar dengan beberapa pengarsip yang mampu mendeteksi pola jarak jauh, misalnya, rzip atau lrzip ( Readme ). Keduanya menggunakan deteksi / deduplikasi redundensi jarak jauh, kemudian rzip menggunakan bzip2 dan lrzip menggunakan xz (lzma) / ZPAQ:

rzip adalah program kompresi, fungsionalitasnya mirip dengan gzip atau bzip2, tetapi mampu memanfaatkan redundensi jarak jauh dalam file, yang kadang-kadang memungkinkan rzip untuk menghasilkan rasio kompresi yang jauh lebih baik daripada program lain. ... Keuntungan utama rzip adalah rzip memiliki buffer sejarah efektif sebesar 900 Mbyte. Ini berarti dapat menemukan potongan yang cocok dari file input pada jarak yang sangat jauh dibandingkan dengan program kompresi yang biasa digunakan lainnya. Program gzip dengan perbandingan menggunakan buffer sejarah 32 kbyte dan bzip2 menggunakan buffer sejarah 900 kbyte

lrzip memiliki buffer yang lebih besar dan dapat menggunakan banyak algoritma kompresi (sangat cepat, cepat, bagus, dan salah satu yang terbaik - ZPAQ) setelah deduplikasi:

Lrzip menggunakan versi diperpanjang rzip yang melakukan redundansi reduksi jarak jauh pertama. Modifikasi lrzip membuatnya skala sesuai dengan ukuran memori.

Data tersebut kemudian: 1. Dikompresi oleh lzma (default) yang memberikan kompresi yang sangat baik di sekitar dua kali kecepatan kompresi bzip2 ...

Cara lain adalah menggunakan bup - program cadangan dengan deduplikasi tingkat blok / segmen, berdasarkan git packfile:

Ini menggunakan algoritma checksum bergulir (mirip dengan rsync) untuk membagi file besar menjadi potongan.

osgx
sumber