ホームページ > Java > &#&チュートリアル > Parquet Java の圧縮アルゴリズム

Parquet Java の圧縮アルゴリズム

Mary-Kate Olsen
リリース: 2025-01-20 18:04:12
オリジナル
931 人が閲覧しました

Compression algorithms in Parquet Java

Apache Parquet は分析ワークロードを対象とした列指向のストレージ形式ですが、あらゆる種類の構造化データの保存に使用でき、さまざまなユースケースに対応できます。

その最も注目すべき機能の 1 つは、処理プロセスの両方の段階で異なる圧縮技術を使用してデータを効率的に圧縮できることです。これにより、ストレージ コストが削減され、読み取りパフォーマンスが向上します。

この記事では、Java での Parquet のファイル圧縮について説明し、使用例を示し、そのパフォーマンスを分析します。

圧縮技術

従来の行ベースのストレージ形式とは異なり、Parquet は列指向のアプローチを使用し、同じ種類のデータの局所性と値の冗長性に基づいて、より具体的で効率的な圧縮技術を使用できます。

Parquet は情報をバイナリ形式で書き込み、それぞれ異なる技術を使用して 2 つの異なるレベルで圧縮を適用します。

  • 列の値を書き込む際、初期値の特性に応じてエンコード タイプ (辞書エンコード、ランレングス エンコード、ビット パッキング、インクリメンタル エンコードなど) が適応的に選択されます。
  • 特定のバイト数 (デフォルトは 1MB) に達すると、ページが形成され、プログラマが構成可能なアルゴリズム (圧縮なし、GZip、Snappy、LZ4、ZSTD など) を使用してバイナリ ブロックが圧縮されます。

圧縮アルゴリズムはファイル レベルで構成されますが、各列のエンコーディングは内部ヒューリスティックを使用して自動的に選択されます (少なくとも parquet-java 実装では)。

さまざまな圧縮テクノロジーのパフォーマンスはデータに大きく依存するため、最速の処理時間と最小のストレージ消費量を保証する万能のソリューションはありません。 独自のテストを実行する必要があります

コード

設定は簡単で、書き込み時に明示的に設定するだけです。ファイルを読み取るときに、Parquet は使用されている圧縮アルゴリズムを検出し、対応する解凍アルゴリズムを適用します。

アルゴリズムまたはコーデックを構成する

プロトコル バッファーと Avro を使用する Carpet と Parquet で圧縮アルゴリズムを構成するには、ビルダーの withCompressionCodec メソッドを呼び出すだけです。

カーペット

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

アブロ

<code class="language-java">ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile)
    .withSchema(new Organization().getSchema())
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー

プロトコルバッファ

<code class="language-java">ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile)
    .withMessage(Organization.class)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー

値は、CompressionCodecName 列挙で使用可能な値のいずれかである必要があります: UNCOMPRESSED、SNAPPY、GZIP、LZO、BROTLI、LZ4、ZSTD、LZ4_RAW (LZ4 は非推奨なので、LZ4_RAW を使用する必要があります)。

圧縮レベル

一部の圧縮アルゴリズムには、圧縮レベルを微調整する方法が用意されています。このレベルは通常、繰り返しパターンを見つけるのにどれだけの労力を費やす必要があるかに関係しており、圧縮レベルが高くなるほど、圧縮プロセスに必要な時間とメモリが増えます。

デフォルト値が付属していますが、コーデックごとに異なるキーを使用する場合でも、Parquet の汎用構成メカニズムを使用して変更できます。

さらに、選択する値は標準ではなく、各コーデックに依存するため、各レベルが提供するものを理解するには、各アルゴリズムのドキュメントを参照する必要があります。

ZSTD

レベル設定を参照するために、ZSTD コーデックは定数 ZstandardCodec.PARQUET_COMPRESS_ZSTD_LEVEL を宣言します。

可能な値の範囲は 1 ~ 22 で、デフォルト値は 3 です。

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

LZO

レベル設定を参照するために、LZO コーデックは定数 LzoCodec.LZO_COMPRESSION_LEVEL_KEY を宣言します。

可能な値の範囲は 1 ~ 9、99、999 で、デフォルト値は「999」です。

<code class="language-java">ParquetWriter<Organization> writer = AvroParquetWriter.<Organization>builder(outputFile)
    .withSchema(new Organization().getSchema())
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー

GZIP

定数は宣言されていません。文字列「zlib.compress.level」を直接使用する必要があります。可能な値の範囲は 0 ~ 9 で、デフォルト値は「6」です。

<code class="language-java">ParquetWriter<Organization> writer = ProtoParquetWriter.<Organization>builder(outputFile)
    .withMessage(Organization.class)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー

パフォーマンステスト

さまざまな圧縮アルゴリズムのパフォーマンスを分析するために、異なるタイプのデータを含む 2 つの公開データセットを使用します。

  • ニューヨーク市のタクシー旅行: いくつかの列に多数の数値と少数の文字列値が含まれています。 23 列があり、1,960 万件のレコードが含まれています。
  • イタリア政府の結束プロジェクト: 多くの列には浮動小数点値と多数のさまざまなテキスト文字列が含まれています。 91 列があり、200 万行が含まれています。

Parquet Java で有効になっているいくつかの圧縮アルゴリズム (UNCOMPRESSED、SNAPPY、GZIP、LZO、ZSTD、LZ4_RAW) を評価します。

予想どおり、parquet-java が提供するデフォルト設定と各アルゴリズムのデフォルト圧縮レベルで Carpet を使用します。

ソース コードは GitHub で見つけることができます。テストは AMD Ryzen 7 4800HS CPU と JDK 17 を搭載したラップトップで行われました。

ファイルサイズ

各圧縮のパフォーマンスを理解するために、同等の CSV ファイルを参照として使用します。

格式 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

2 つのテストのうち、GZip と Zstandard を使用した圧縮が最も効率的でした。

Parquet エンコード技術のみを使用すると、ファイル サイズを元の CSV サイズの 25% ~ 32% に削減できます。さらに圧縮を適用すると、CSV サイズの 9% ~ 15% に縮小されます。

書く

情報を圧縮するとどれくらいのオーバーヘッドが発生しますか?

同じ情報を 3 回書き込み、平均秒数を計算すると、次のようになります。

算法 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、LZO は圧縮なしの場合と同様の時間を達成しますが、ZSTD ではオーバーヘッドが追加されます。 GZIP のパフォーマンスは最悪で、書き込み時間が 50% 遅くなりました。

読む

ファイルの読み取りは、必要な計算量が少ないため、書き込みよりも高速です。

ファイル内のすべての列を読み取るのにかかる時間 (秒):

算法 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

読み取り時間は非圧縮情報の読み取り時間に近く、解凍のオーバーヘッドは 10% ~ 20% です。

結論

読み取り時間と書き込み時間の点で他のアルゴリズムより大幅に優れているアルゴリズムはなく、すべて同様の範囲内にあります。 ほとんどの場合、情報を圧縮すると、スペースの節約 (および送信) 時間の損失を補うことができます

これら 2 つの使用例では、どちらかのアルゴリズムを選択する決定要因は、おそらく達成される圧縮率であり、ZSTD と Gzip が顕著です (ただし、書き込み時間は劣ります)。

各アルゴリズムにはそれぞれ利点があるため、最良のオプションは、データを使用してテストし、どの要素がより重要であるかを検討することです。

  • めったに使用されない大量のデータを保存するため、ストレージの使用量を最小限に抑えます。
  • ファイルの生成時間を最小限に抑えます。
  • ファイルは複数回読み取られるため、読み取り時間を最小限に抑えます。

人生のすべてのことと同様、それはトレードオフであり、それを最もよく補うものを考える必要があります。 Carpet では、何も設定しない場合、デフォルトで圧縮に Snappy が使用されます。

実装の詳細

値は、CompressionCodecName 列挙で使用可能な値の 1 つである必要があります。各列挙値には、アルゴリズムを実装するクラスの名前が関連付けられます:

<code class="language-java">CarpetWriter<T> writer = new CarpetWriter.Builder<>(outputFile, clazz)
    .withCompressionCodec(CompressionCodecName.ZSTD)
    .build();</code>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

Parquet はリフレクションを使用して指定されたクラスをインスタンス化します。このクラスは CompressionCodec インターフェイスを実装する必要があります。そのソース コードを見ると、それが Parquet ではなく Hadoop プロジェクトにあることがわかります。これは、Parquet が Java 実装において Hadoop といかにうまく連携しているかを示しています。

これらのコーデックのいずれかを使用するには、その実装を含む JAR を依存関係として追加していることを確認する必要があります。

parquet-java を追加するときに、推移的な依存関係にすべての実装が存在するわけではありません。あるいは、Hadoop の依存関係を積極的に除外しすぎている可能性があります。

org.apache.parquet:parquet-hadoop 依存関係に、SnappyCodec、ZstandardCodec、Lz4RawCodec の実装を含めます。これらの 3 つのアルゴリズムの実際の実装とともに、snappy-java、zstd-jni、aircompressor 依存関係を推移的にインポートします。 。

hadoop-common:hadoop-common 依存関係には、GzipCodec の実装が含まれます。

BrotliCodec と LzoCodec の実装はどこですか? これらは Parquet または Hadoop の依存関係に含まれていない。そのため、追加の依存関係を追加せずにこれらを使用すると、アプリケーションはこれらの形式で圧縮されたファイルを使用できなくなります。

  • LZO をサポートするには、依存関係 org.anarres.lzo:lzo-hadoop を pom または gradle ファイルに追加する必要があります。
  • Brotli の状況はさらに複雑です。依存関係は Maven Central になく、JitPack リポジトリも追加する必要があります。

以上がParquet Java の圧縮アルゴリズムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート