Rumah > Java > javaTutorial > Algoritma mampatan dalam Parquet Java

Algoritma mampatan dalam Parquet Java

Mary-Kate Olsen
Lepaskan: 2025-01-20 18:04:12
asal
931 orang telah melayarinya

Compression algorithms in Parquet Java

Park Apache ialah format storan kolumnar yang disasarkan pada beban kerja analisis, tetapi ia boleh digunakan untuk menyimpan sebarang jenis data berstruktur, menangani pelbagai kes penggunaan.

Salah satu ciri yang paling ketara ialah keupayaan untuk memampatkan data dengan cekap menggunakan teknik pemampatan berbeza pada kedua-dua peringkat proses pemprosesan. Ini mengurangkan kos penyimpanan dan meningkatkan prestasi bacaan.

Artikel ini menerangkan pemampatan fail Parket dalam Java, menyediakan contoh penggunaan dan menganalisis prestasinya.

Teknologi pemampatan

Tidak seperti format storan berasaskan baris tradisional, Parket menggunakan pendekatan kolumnar, membenarkan penggunaan teknik pemampatan yang lebih khusus dan cekap berdasarkan lokaliti dan lebihan nilai bagi jenis data yang sama.

Parquet menulis maklumat dalam format binari dan menggunakan pemampatan pada dua tahap berbeza, setiap satu menggunakan teknik yang berbeza:

  • Apabila menulis nilai lajur, ia akan menyesuaikan jenis pengekodan mengikut ciri nilai awal: pengekodan kamus, pengekodan panjang larian, pembungkusan bit, pengekodan tambahan, dsb.
  • Apabila bilangan bait tertentu dicapai (lalai ialah 1MB), halaman terbentuk dan blok binari dimampatkan menggunakan algoritma boleh dikonfigurasikan pengaturcara (tiada mampatan, GZip, Snappy, LZ4, ZSTD, dll.).

Walaupun algoritma pemampatan dikonfigurasikan pada peringkat fail, pengekodan setiap lajur dipilih secara automatik menggunakan heuristik dalaman (sekurang-kurangnya dalam pelaksanaan parket-java).

Prestasi teknologi pemampatan yang berbeza sangat bergantung pada data anda, jadi tiada penyelesaian satu saiz yang sesuai untuk semua yang menjamin masa pemprosesan terpantas dan penggunaan storan terendah. Anda perlu melakukan ujian anda sendiri.

Kod

Konfigurasi adalah mudah dan hanya memerlukan tetapan yang jelas semasa menulis. Apabila membaca fail, Parket menemui algoritma pemampatan yang digunakan dan menggunakan algoritma penyahmampatan yang sepadan.

Konfigurasikan algoritma atau codec

Dalam Permaidani dan Parket menggunakan Penampan Protokol dan Avro, untuk mengkonfigurasi algoritma pemampatan, cuma panggil pembina dengan kaedahCompressionCodec:

Permaidani

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Avro

<code class="language-java">ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile)
    .withSchema(new Organization().getSchema())
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk

Penimbal Protokol

<code class="language-java">ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile)
    .withMessage(Organization.class)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk

Nilai mestilah salah satu nilai yang tersedia dalam penghitungan CompressionCodecName: UNCOMPRESSED, SNAPPY, GZIP, LZO, BROTLI, LZ4, ZSTD dan LZ4_RAW (LZ4 ditamatkan, LZ4_RAW harus digunakan).

Tahap mampatan

Sesetengah algoritma mampatan menyediakan cara untuk memperhalusi tahap mampatan. Tahap ini biasanya berkaitan dengan berapa banyak usaha yang mereka perlukan untuk mencari corak berulang; semakin tinggi tahap mampatan, lebih banyak masa dan ingatan yang diperlukan oleh proses mampatan.

Walaupun ia disertakan dengan nilai lalai, ia boleh diubah suai menggunakan mekanisme konfigurasi generik Parket, walaupun menggunakan kekunci berbeza untuk setiap codec.

Selain itu, nilai untuk dipilih adalah tidak standard dan bergantung pada setiap codec, jadi anda mesti merujuk kepada dokumentasi untuk setiap algoritma untuk memahami perkara yang ditawarkan oleh setiap tahap.

ZSTD

Untuk konfigurasi tahap rujukan, codec ZSTD mengisytiharkan pemalar: ZstandardCodec.PARQUET_COMPRESS_ZSTD_LEVEL.

Nilai yang mungkin berjulat dari 1 hingga 22, nilai lalai ialah 3.

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

LZO

Untuk konfigurasi tahap rujukan, codec LZO mengisytiharkan pemalar: LzoCodec.LZO_COMPRESSION_LEVEL_KEY.

Nilai yang mungkin berjulat dari 1 hingga 9, 99 dan 999, dengan nilai lalai ialah '999'.

<code class="language-java">ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile)
    .withSchema(new Organization().getSchema())
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk

GZIP

Ia tidak mengisytiharkan sebarang pemalar, anda mesti menggunakan rentetan "zlib.compress.level" secara langsung, nilai kemungkinan antara 0 hingga 9, nilai lalai ialah "6".

<code class="language-java">ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile)
    .withMessage(Organization.class)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk

Ujian Prestasi

Untuk menganalisis prestasi algoritma pemampatan yang berbeza, saya akan menggunakan dua set data awam yang mengandungi jenis data yang berbeza:

  • Perjalanan Teksi New York City: Mengandungi sejumlah besar angka dan sejumlah kecil nilai rentetan dalam beberapa lajur. Ia mempunyai 23 lajur dan mengandungi 19.6 juta rekod.
  • Projek Kohesi Kerajaan Itali: Banyak lajur mengandungi nilai titik terapung serta sejumlah besar pelbagai rentetan teks. Ia mempunyai 91 lajur dan mengandungi 2 juta baris.

Saya akan menilai beberapa algoritma mampatan yang didayakan dalam Parquet Java: UNCOMPRESSED, SNAPPY, GZIP, LZO, ZSTD, LZ4_RAW.

Seperti yang dijangkakan, saya akan menggunakan Carpet dengan konfigurasi lalai yang disediakan oleh parket-java dan tahap mampatan lalai untuk setiap algoritma.

Anda boleh mencari kod sumber di GitHub, ujian telah dilakukan pada komputer riba dengan CPU AMD Ryzen 7 4800HS dan JDK 17.

Saiz fail

Untuk memahami prestasi setiap pemampatan, kami akan menggunakan fail CSV yang setara sebagai rujukan.

格式 gov.it 纽约出租车
CSV 1761 MB 2983 MB
未压缩 564 MB 760 MB
SNAPPY 220 MB 542 MB
GZIP **146 MB** 448 MB
ZSTD 148 MB **430 MB**
LZ4_RAW 209 MB 547 MB
LZO 215 MB 518 MB

Daripada dua ujian, pemampatan menggunakan GZip dan Zstandard adalah yang paling berkesan.

Hanya menggunakan teknologi pengekodan Parket, saiz fail boleh dikecilkan kepada 25%-32% daripada saiz CSV asal. Dengan pemampatan tambahan digunakan, ia akan dikurangkan kepada 9% hingga 15% daripada saiz CSV.

Tulis

Berapa banyak overhed yang dibawa oleh maklumat memampatkan?

Jika kita menulis maklumat yang sama tiga kali dan mengira purata saat, kita mendapat:

算法 gov.it 纽约出租车
未压缩 25.0 57.9
SNAPPY 25.2 56.4
GZIP 39.3 91.1
ZSTD 27.3 64.1
LZ4_RAW **24.9** 56.5
LZO 26.0 **56.1**

SNAPPY, LZ4 dan LZO mencapai masa yang sama tanpa pemampatan, manakala ZSTD menambah beberapa overhed. GZIP mempunyai prestasi yang paling teruk, dengan masa tulis menjadi perlahan sebanyak 50%.

Baca

Membaca fail lebih pantas daripada menulis kerana kurang pengiraan diperlukan.

Masa dalam beberapa saat untuk membaca semua lajur dalam fail ialah:

算法 gov.it 纽约出租车
未压缩 11.4 37.4
SNAPPY **12.5** **39.9**
GZIP 13.6 40.9
ZSTD 13.1 41.5
LZ4_RAW 12.8 41.6
LZO 13.1 41.1

Masa membaca adalah hampir dengan maklumat yang tidak dimampatkan dan overhed penyahmampatan adalah antara 10% dan 20%.

Kesimpulan

Tiada algoritma yang jauh lebih baik daripada yang lain dari segi masa baca dan tulis, semuanya berada dalam julat yang sama. Dalam kebanyakan kes, memampatkan maklumat boleh menggantikan penjimatan ruang (dan penghantaran) masa yang hilang.

Dalam kedua-dua kes penggunaan ini, faktor penentu dalam memilih satu atau algoritma lain mungkin adalah nisbah mampatan yang dicapai, dengan ZSTD dan Gzip menonjol (tetapi masa penulisan adalah lebih rendah).

Setiap algoritma mempunyai kelebihannya, jadi pilihan terbaik ialah mengujinya dengan data anda dan pertimbangkan faktor mana yang lebih penting:

  • Meminimumkan penggunaan storan semasa anda menyimpan sejumlah besar data yang jarang digunakan.
  • Meminimumkan masa penjanaan fail.
  • Minimumkan masa membaca kerana fail dibaca berbilang kali.

Seperti segala-galanya dalam kehidupan, ia adalah satu pertukaran dan anda perlu melihat apa yang terbaik mengimbanginya. Dalam Permaidani, secara lalai ia menggunakan Snappy untuk pemampatan jika anda tidak mengkonfigurasi apa-apa.

Butiran pelaksanaan

Nilai mestilah salah satu nilai yang tersedia dalam penghitungan CompressionCodecName. Dikaitkan dengan setiap nilai penghitungan ialah nama kelas yang melaksanakan algoritma:

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
Salin selepas log masuk
Salin selepas log masuk
Salin selepas log masuk

Parquet akan menggunakan pantulan untuk membuat contoh kelas yang ditentukan, yang mesti melaksanakan antara muka CompressionCodec. Jika anda melihat kod sumbernya, anda akan melihat bahawa ia berada dalam projek Hadoop, bukan Parket. Ini menunjukkan sejauh mana Parket digandingkan dengan Hadoop dalam pelaksanaan Javanya.

Untuk menggunakan salah satu codec ini, anda mesti memastikan bahawa anda telah menambahkan JAR yang mengandungi pelaksanaannya sebagai kebergantungan.

Tidak semua pelaksanaan terdapat dalam kebergantungan transitif yang anda miliki semasa menambah parket-java, atau anda mungkin mengecualikan kebergantungan Hadoop secara terlalu agresif.

Dalam kebergantungan org.apache.parquet:parquet-hadoop, sertakan pelaksanaan SnappyCodec, ZstandardCodec dan Lz4RawCodec, yang secara transitif mengimport kebergantungan snappy-java, zstd-jni dan pemampat udara bersama-sama dengan pelaksanaan sebenar ketiga-tiga algoritma ini .

Dalam pergantungan hadoop-common:hadoop-common, mengandungi pelaksanaan GzipCodec.

Di manakah pelaksanaan BrotliCodec dan LzoCodec? Ia tidak berada dalam mana-mana kebergantungan Parket atau Hadoop, jadi jika anda menggunakannya tanpa menambah kebergantungan tambahan, aplikasi anda tidak akan dapat menggunakan fail yang dimampatkan dalam format tersebut.

  • Untuk menyokong LZO, anda perlu menambahkan dependency org.anarres.lzo:lzo-hadoop pada fail pom atau gradle anda.
  • Situasi dengan Brotli lebih rumit: pergantungan tidak ada dalam Maven Central dan anda juga mesti menambah repositori JitPack.

Atas ialah kandungan terperinci Algoritma mampatan dalam Parquet Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan