このリポジトリには、Parquet メタデータを読み書きするための Apache Parquet および Apache Thrift 定義の仕様が含まれています。
Apache Parquet は、効率的なデータの保存と取得のために設計されたオープンソースの列指向のデータ ファイル形式です。複雑なデータを一括処理するための高性能の圧縮およびエンコード スキームを提供し、多くのプログラミング言語や分析ツールでサポートされています。
私たちは、圧縮された効率的な列形式データ表現の利点を Hadoop エコシステム内のあらゆるプロジェクトで利用できるようにするために、Parquet を作成しました。
Parquet は、複雑なネストされたデータ構造を念頭に置いてゼロから構築されており、Dremel の論文で説明されているレコードのシュレッディングとアセンブリのアルゴリズムを使用します。このアプローチは、ネストされた名前空間を単純にフラット化するよりも優れていると考えられます。
Parquet は、非常に効率的な圧縮およびエンコード スキームをサポートするように構築されています。複数のプロジェクトで、適切な圧縮およびエンコード スキームをデータに適用することによるパフォーマンスへの影響が実証されています。 Parquet を使用すると、圧縮スキームを列ごとのレベルで指定でき、将来も保証されており、エンコーディングが発明され実装されるたびに追加できるようになります。
寄木細工は誰でも使えるように作られています。 Hadoop エコシステムにはデータ処理フレームワークが豊富にあり、私たちはお気に入りをプレイすることに興味はありません。私たちは、効率的で適切に実装された円柱型ストレージ基板は、セットアップが困難で広範な依存関係にコストをかけることなく、すべてのフレームワークに役立つはずだと信じています。
parquet-format
プロジェクトには、Parquet ファイルを適切に読み取るために必要なメタデータの形式仕様と Thrift 定義が含まれています。
parquet-java
プロジェクトには複数のサブモジュールが含まれており、ネストされた列指向のデータ ストリームの読み取りと書き込みのコア コンポーネントを実装し、このコアを寄木細工形式にマップし、Hadoop 入出力形式、Pig ローダーなどを提供します。 Parquet と対話するための Java ベースのユーティリティ。
parquet-compatibility
プロジェクトには、異なる言語の実装が相互にファイルを読み書きできることを検証するために使用できる互換性テストが含まれています。
Java リソースは、 mvn package
使用して構築できます。現在の安定バージョンは常に Maven Central から入手できるはずです。
C++ の節約リソースは、make を通じて生成できます。
Thrift は、Thrift がサポートされている他の言語にコード生成することもできます。
ブロック (HDFS ブロック): これは HDFS 内のブロックを意味し、このファイル形式を記述する意味は変わりません。このファイル形式は、HDFS 上で適切に動作するように設計されています。
ファイル: ファイルのメタデータを含む必要がある HDFS ファイル。実際にデータを含める必要はありません。
行グループ: データを行に論理的に水平に分割したもの。行グループに対して保証される物理構造はありません。行グループは、データセット内の各列の列チャンクで構成されます。
列チャンク: 特定の列のデータのチャンク。これらは特定の行グループ内に存在し、ファイル内で連続していることが保証されます。
ページ: 列チャンクはページに分割されます。ページは、概念的には (圧縮とエンコードの観点から) 分割できない単位です。列チャンク内に複数のページ タイプがインターリーブされる場合があります。
階層的には、ファイルは 1 つ以上の行グループで構成されます。行グループには、列ごとに 1 つの列チャンクが含まれます。列チャンクには 1 つ以上のページが含まれます。
形式を理解するには、このファイルと Thrift 定義を一緒に読む必要があります。
4-byte magic number "PAR1"
<Column 1 Chunk 1>
<Column 2 Chunk 1>
...
<Column N Chunk 1>
<Column 1 Chunk 2>
<Column 2 Chunk 2>
...
<Column N Chunk 2>
...
<Column 1 Chunk M>
<Column 2 Chunk M>
...
<Column N Chunk M>
File Metadata
4-byte length in bytes of file metadata (little endian)
4-byte magic number "PAR1"
上の例では、このテーブルには N 列があり、M 行グループに分割されています。ファイルのメタデータには、すべての列チャンクの開始位置の場所が含まれています。メタデータに含まれる内容の詳細については、Thrift の定義を参照してください。
シングルパス書き込みを可能にするために、ファイル メタデータはデータの後に書き込まれます。
読み取り者は、最初にファイルのメタデータを読み取り、関心のあるすべての列チャンクを見つけることが期待されます。その後、列チャンクを順番に読み取る必要があります。
メタデータには、ファイル メタデータとページ ヘッダー メタデータの 2 種類があります。すべての節約構造は、TCompactProtocol を使用してシリアル化されます。
ファイル形式でサポートされる種類は、種類がディスク ストレージにどのような影響を与えるかに重点を置き、可能な限り最小限になるように設計されています。たとえば、16 ビット int は、効率的なエンコーディングを備えた 32 ビット int によってカバーされるため、ストレージ形式では明示的にサポートされていません。これにより、その形式のリーダーとライターの実装の複雑さが軽減されます。種類は次のとおりです。
論理型は、プリミティブ型の解釈方法を指定することにより、parquet で保存できる型を拡張するために使用されます。これにより、プリミティブ型のセットが最小限に抑えられ、parquet の効率的なエンコーディングが再利用されます。たとえば、文字列は STRING アノテーションが付いたプリミティブ型 BYTE_ARRAY で保存されます。これらのアノテーションは、データをさらにデコードして解釈する方法を定義します。注釈はファイルのメタデータにLogicalType
フィールドとして保存され、LogicalTypes.md に文書化されます。
Parquet は、最小/最大統計を複数のレベル (列チャンク、列インデックス、データ ページなど) で保存します。型の値の比較は、次の規則に従います。
各論理タイプには指定された比較順序があります。列に不明な論理タイプの注釈が付けられている場合、統計はデータのプルーニングに使用されない可能性があります。論理タイプの並べ替え順序は、LogicalTypes.md ページに記載されています。
プリミティブ型の場合、次のルールが適用されます。
ブール値 - false、true
INT32、INT64 - 符号付き比較。
FLOAT、DOUBLE - NaN および符号付きゼロの特別な処理を伴う符号付き比較。詳細は、 ColumnOrder
ユニオンの Thrift 定義に文書化されています。それらはここに要約されていますが、Thrift の定義は信頼できると考えられています。
+0.0
書き込む必要があります。-0.0
書き込む必要があります。ファイル読み取り時の下位互換性のために:
BYTE_ARRAY および FIXED_LEN_BYTE_ARRAY - 辞書編集的な符号なしのバイト単位の比較。
ネストされた列をエンコードするために、Parquet は定義レベルと繰り返しレベルを備えた Dremel エンコードを使用します。定義レベルは、列のパスに定義されるオプションのフィールドの数を指定します。繰り返しレベルは、パス内のどの繰り返しフィールドで値が繰り返されるかを指定します。最大定義レベルと繰り返しレベルは、スキーマ (つまり、ネストの量) から計算できます。これは、レベルを格納するために必要な最大ビット数を定義します (レベルは列内のすべての値に対して定義されます)。
レベルの 2 つのエンコーディングが BIT_PACKED と RLE でサポートされています。 BIT_PACKED に取って代わられるため、現在は RLE のみが使用されています。
ヌル値は定義レベルでエンコードされます (ランレングス エンコードされます)。 NULL 値はデータ内でエンコードされません。たとえば、ネストされていないスキーマでは、1000 個の NULL を持つ列は、定義レベルのランレングス エンコード (0、1000 回) でエンコードされ、それ以外は何もエンコードされません。
データ ページの場合、3 つの情報はページ ヘッダーの後に連続してエンコードされます。データ ページではパディングは許可されません。順序としては次のとおりです。
ヘッダーで指定されるuncompressed_page_size
の値は、3 つの部分をすべて組み合わせたものです。
データ ページのエンコードされた値は常に必要です。定義および繰り返しレベルは、スキーマ定義に基づいてオプションです。列がネストされていない場合 (つまり、列へのパスの長さが 1 である場合)、繰り返しレベルはエンコードされません (値は常に 1 になります)。必要なデータについては、定義レベルはスキップされます (エンコードされている場合、常に最大定義レベルの値になります)。
たとえば、列がネストされておらず必須である場合、ページ内のデータはエンコードされた値のみです。
サポートされているエンコーディングは Encodings.md に記載されています。
サポートされている圧縮コーデックは Compression.md に記載されています。
列チャンクは、連続して書き込まれるページで構成されます。ページは共通のヘッダーを共有しており、読者は興味のないページをスキップできます。ページのデータはヘッダーに続き、圧縮および/またはエンコードできます。圧縮とエンコードはページのメタデータで指定されます。
列チャンクは、部分的または完全に辞書エンコードされている場合があります。これは、辞書インデックスが実際の値の代わりにデータ ページに保存されることを意味します。実際の値は辞書ページに保存されます。詳細については、Encodings.md を参照してください。辞書ページは列チャンクの最初の位置に配置する必要があります。列チャンクには最大 1 つの辞書ページを配置できます。
さらに、ファイルにはオプションの列インデックスを含めることができ、読者がより効率的にページをスキップできるようになります。詳細と、これらを形式に追加する理由については、PageIndex.md を参照してください。
あらゆる種類のページを個別にチェックサムすることができます。これにより、HDFS ファイル レベルでチェックサムを無効にし、単一行のルックアップをより適切にサポートできるようになります。チェックサムは、ページのシリアル化されたバイナリ表現 (ページ ヘッダー自体は含まない) に対して、GZip などで使用される標準 CRC32 アルゴリズムを使用して計算されます。
ファイルのメタデータが破損している場合、ファイルは失われます。列のメタデータが破損している場合、その列チャンクは失われます (ただし、他の行グループ内のこの列の列チャンクは問題ありません)。ページ ヘッダーが破損している場合、そのチャンク内の残りのページは失われます。ページ内のデータが破損している場合、そのページは失われます。行グループが小さいほど、ファイルの破損に対する回復力が高くなります。
拡張の可能性: 行グループが小さい場合、最大の問題はファイルのメタデータを最後に配置することです。ファイルのメタデータの書き込み中にエラーが発生した場合、書き込まれたすべてのデータは読み取ることができなくなります。これは、N 番目の行グループごとにファイルのメタデータを書き込むことで修正できます。各ファイルのメタデータは累積的であり、これまでに書き込まれたすべての行グループが含まれます。これを、同期マーカーを使用して rc または avro ファイルに使用する戦略と組み合わせると、リーダーは部分的に書き込まれたファイルを回復できます。
この形式は、メタデータをデータから分離するように明示的に設計されています。これにより、列を複数のファイルに分割したり、単一のメタデータ ファイルで複数の寄せ木細工のファイルを参照したりすることができます。
互換性のある拡張子がフォーマット内に数多く存在します。
Parquet Thrift IDL は、拡張機能用にすべての Thrift 構造体のフィールド ID 32767
予約します。このフィールドの (Thrift) タイプは常にbinary
です。
apache/parquet-testing には、テスト目的の Parquet ファイルのセットが含まれています。
問題についてコメントするか、質問やアイデアを parquet-dev メーリング リストに連絡してください。このコアフォーマット定義への変更が提案され、メーリングリストで詳細に議論されています。すべての Java 側の実装と API が含まれる Parquet-Java サブプロジェクトへの貢献にも興味があるかもしれません。 Parquet-Java プロジェクトの「貢献方法」セクションを参照してください。
私たち自身と Parquet 開発者コミュニティは、Twitter OSS (https://github.com/twitter/code-of-conduct/blob/master/code-of-conduct.md) で説明されている行動規範を遵守します。
著作権は 2013 Twitter、Cloudera、およびその他の寄稿者に帰属します。
Apache License、バージョン 2.0 に基づいてライセンスされています: http://www.apache.org/licenses/LICENSE-2.0