Memanfaatkan multi-core untuk tar + gzip / bzip kompresi / dekompresi

225

Saya biasanya mengompres menggunakan tar zcvfdan menggunakan kompresi tar zxvf(menggunakan gzip karena kebiasaan).

Saya baru saja mendapatkan CPU quad core dengan hyperthreading, jadi saya memiliki 8 core logis, dan saya perhatikan bahwa banyak core yang tidak digunakan selama kompresi / dekompresi.

Apakah ada cara saya bisa memanfaatkan inti yang tidak digunakan untuk membuatnya lebih cepat?

pengguna1118764
sumber
Solusi yang diusulkan oleh Xiong Chiamiov di atas berfungsi dengan baik. Saya baru saja mencadangkan laptop saya dengan .tar.bz2 dan butuh 132 menit hanya menggunakan satu utas cpu. Kemudian saya mengkompilasi dan menginstal tar dari sumber: gnu.org/software/tar. Saya menyertakan opsi yang disebutkan dalam langkah configure: ./configure --with-gzip = pigz --with-bzip2 = lbzip2 --with-lzip = plzip Saya menjalankan cadangan lagi dan hanya butuh 32 menit. Itu lebih baik daripada peningkatan 4X! Saya menonton monitor sistem dan menjaga semua 4 CPU (8 thread) rata pada 100% sepanjang waktu. ITULAH solusi terbaik.
Warren Severin

Jawaban:

309

Anda dapat menggunakan pigz bukan gzip, yang melakukan kompresi gzip pada beberapa core. Alih-alih menggunakan opsi -z, Anda akan mengirimkannya melalui pigz:

tar cf - paths-to-archive | pigz > archive.tar.gz

Secara default, pigz menggunakan jumlah core yang tersedia, atau delapan jika tidak bisa menanyakan itu. Anda dapat meminta lebih banyak dengan -pn, misalnya -p 32. pigz memiliki opsi yang sama dengan gzip, sehingga Anda dapat meminta kompresi yang lebih baik dengan -9. Misalnya

tar cf - paths-to-archive | pigz -9 -p 32 > archive.tar.gz
Mark Adler
sumber
3
Bagaimana Anda menggunakan pigz untuk melakukan dekompresi dengan cara yang sama? Atau apakah itu hanya berfungsi untuk kompresi?
user788171
42
pigz memang menggunakan banyak inti untuk dekompresi, tetapi hanya dengan peningkatan terbatas pada satu inti. Format deflate tidak cocok untuk dekompresi paralel. Bagian dekompresi harus dilakukan secara serial. Inti lain untuk dekompresi pigz digunakan untuk membaca, menulis, dan menghitung CRC. Ketika mengompresi di sisi lain, pigz akan dekat dengan faktor n perbaikan dengan n core.
Mark Adler
7
Tanda hubung di sini adalah stdout (lihat halaman ini ).
Garrett
3
Iya. 100% kompatibel di kedua arah.
Mark Adler
4
Secara efektif tidak ada waktu CPU yang dihabiskan untuk tarring, jadi itu tidak akan banyak membantu. Format tar hanyalah salinan dari file input dengan blok header di antara file.
Mark Adler
324

Anda juga dapat menggunakan flag tar "--use-compress-program =" untuk memberi tahu tar program kompresi apa yang digunakan.

Misalnya gunakan:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip 
Jen
sumber
21
Ini adalah nugget kecil yang luar biasa dari pengetahuan dan layak mendapatkan lebih banyak upvotes. Saya tidak tahu pilihan ini bahkan ada dan saya telah membaca halaman manual beberapa kali selama bertahun-tahun.
Randall Hunt
2
@ValerioSchiavoni: Tidak di sini, saya mendapatkan beban penuh pada semua 4 core (Ubuntu 15,04 'Jelas').
bovender
8
Saya lebih suka tar - dir_to_zip | pv | pigz > tar.filepv membantu saya memperkirakan, Anda bisa melewatkannya. Tetapi tetap lebih mudah untuk menulis dan mengingat.
Offenso
@ NathanS.Watson-Haigh Ya, benar. Cukup lampirkan nama program dan argumen dalam tanda kutip. man tarmengatakan demikian, seperti halnya ini .
Marc.2377
1
Pada tahun 2020, zstdadalah alat tercepat untuk melakukan ini. Speedup terlihat saat mengompresi dan mendekompresi. Gunakan tar -cf --use-compress-program=zstdmtuntuk melakukannya dengan multi-threading.
jadelord
112

Pendekatan umum

Ada opsi untuk tarprogram:

-I, --use-compress-program PROG
      filter through PROG (must accept -d)

Anda dapat menggunakan utilitas pengarsipan atau kompresor versi multithread.

Pengarsip multithread yang paling populer adalah pigz (bukan gzip) dan pbzip2 (bukan bzip2). Misalnya:

$ tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 paths_to_archive
$ tar --use-compress-program=pigz -cf OUTPUT_FILE.tar.gz paths_to_archive

Pengarsip harus menerima -d. Jika utilitas pengganti Anda tidak memiliki parameter ini dan / atau Anda perlu menentukan parameter tambahan, maka gunakan pipa (tambahkan parameter jika perlu):

$ tar cf - paths_to_archive | pbzip2 > OUTPUT_FILE.tar.gz
$ tar cf - paths_to_archive | pigz > OUTPUT_FILE.tar.gz

Input dan output singlethread dan multithread kompatibel. Anda dapat mengompres menggunakan versi multithread dan mendekompres menggunakan versi singlethread dan sebaliknya.

p7zip

Untuk p7zip untuk kompresi, Anda memerlukan skrip shell kecil seperti berikut:

#!/bin/sh
case $1 in
  -d) 7za -txz -si -so e;;
   *) 7za -txz -si -so a .;;
esac 2>/dev/null

Simpan sebagai 7zhelper.sh. Berikut contoh penggunaannya:

$ tar -I 7zhelper.sh -cf OUTPUT_FILE.tar.7z paths_to_archive
$ tar -I 7zhelper.sh -xf OUTPUT_FILE.tar.7z

xz

Mengenai dukungan XZ multithreaded. Jika Anda menjalankan versi 5.2.0 atau lebih tinggi dari XZ Utils, Anda dapat menggunakan beberapa core untuk kompresi dengan mengatur -Tatau --threadske nilai yang sesuai melalui variabel lingkungan XZ_DEFAULTS (mis XZ_DEFAULTS="-T 0".).

Ini adalah fragmen manusia untuk versi 5.1.0alpha:

Kompresi dan dekompresi multithreaded belum diimplementasikan, sehingga opsi ini tidak berpengaruh untuk saat ini.

Namun ini tidak akan berfungsi untuk dekompresi file yang belum dikompres dengan mengaktifkan threading. Dari manusia untuk versi 5.2.2:

Dekompresi berulir belum diterapkan. Ini hanya akan berfungsi pada file yang berisi banyak blok dengan informasi ukuran di header blok. Semua file yang dikompresi dalam mode multi-threaded memenuhi kondisi ini, tetapi file yang dikompresi dalam mode single-threaded tidak bahkan jika --block-size = size digunakan.

Kompilasi ulang dengan penggantian

Jika Anda membuat tar dari sumber, maka Anda dapat mengkompilasi ulang dengan parameter

--with-gzip=pigz
--with-bzip2=lbzip2
--with-lzip=plzip

Setelah mengkompilasi ulang tar dengan opsi-opsi ini Anda dapat memeriksa output dari bantuan tar:

$ tar --help | grep "lbzip2\|plzip\|pigz"
  -j, --bzip2                filter the archive through lbzip2
      --lzip                 filter the archive through plzip
  -z, --gzip, --gunzip, --ungzip   filter the archive through pigz
Maxim Suslov
sumber
1
Ini memang jawaban terbaik. Saya pasti akan membangun kembali tar saya!
1
Saya baru saja menemukan pbzip2 dan mpibzip2 . mpibzip2 terlihat sangat menjanjikan untuk cluster atau jika Anda memiliki laptop dan komputer desktop multicore misalnya.
Ini adalah jawaban yang bagus dan rumit. Mungkin baik untuk menyebutkan bahwa kompresi multithreaded (misalnya dengan pigz) hanya diaktifkan ketika membaca dari file. Pemrosesan STDIN mungkin lebih lambat.
o
3
Plus 1 untuk xzopsi. Ini pendekatan paling sederhana, namun efektif.
selurvedu
2
export XZ_DEFAULTS="-T 0"sebelum memanggil tardengan opsi -Juntuk kompresi xz bekerja seperti pesona.
scai
13

Anda dapat menggunakan pintasan -Iuntuk --use-compress-programsakelar tar , dan menjalankan pbzip2kompresi bzip2 pada banyak inti:

tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/
panticz
sumber
TL; DR yang bagus untuk jawaban @ MaximSuslov .
einpoklum
Ini mengembalikan tar: home/cc/ziptest: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors`
Arash
1

Jika Anda ingin lebih fleksibel dengan nama file dan opsi kompresi, Anda dapat menggunakan:

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec \
tar -P --transform='s@/my/path/@@g' -cf - {} + | \
pigz -9 -p 4 > myarchive.tar.gz

Langkah 1: find

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec

Perintah ini akan mencari file yang ingin Anda arsipkan, dalam hal ini /my/path/*.sqldan /my/path/*.log. Tambahkan sebanyak yang -o -name "pattern"Anda inginkan.

-execakan menjalankan perintah berikutnya menggunakan hasil dari find:tar

Langkah 2: tar

tar -P --transform='s@/my/path/@@g' -cf - {} +

--transformadalah parameter penggantian string sederhana. Ini akan menghapus jalur file dari arsip sehingga root tarball menjadi direktori saat ini saat mengekstraksi. Perhatikan bahwa Anda tidak dapat menggunakan -Copsi untuk mengubah direktori karena Anda akan kehilangan manfaat dari find: semua file direktori akan disertakan.

-Pmemberitahu taruntuk menggunakan jalur absolut, sehingga tidak memicu peringatan "Menghapus awalan` / 'dari nama anggota ". Memimpin '/' dengan dihapus --transformbagaimanapun juga.

-cf -memberitahu taruntuk menggunakan nama tarball yang akan kita tentukan nanti

{} +menggunakan everyfile yang findditemukan sebelumnya

Langkah 3: pigz

pigz -9 -p 4

Gunakan sebanyak mungkin parameter yang Anda inginkan. Dalam hal ini -9adalah tingkat kompresi dan -p 4jumlah inti yang didedikasikan untuk kompresi. Jika Anda menjalankan ini pada server web yang sarat muatan, Anda mungkin tidak ingin menggunakan semua inti yang tersedia.

Langkah 4: nama arsip

> myarchive.tar.gz

Akhirnya.

Bloops
sumber
0

Alat kompresi (de) yang relatif lebih baru yang mungkin ingin Anda pertimbangkan adalah standar . Itu melakukan pekerjaan yang sangat baik dalam memanfaatkan core cadangan, dan telah membuat beberapa trade-off besar ketika datang ke rasio kompresi vs (de) waktu kompresi. Ini juga sangat dapat disesuaikan tergantung pada kebutuhan rasio kompresi Anda.

pgebhard
sumber