ByteScope

Parquet ファイル形式

Apache Parquet。ビッグデータ分析向けの列指向ストレージ形式。

MIME タイプ
application/vnd.apache.parquet
拡張子
.parquet
カテゴリ
データ・データベース

マジックナンバー(ファイル署名)

0x0000000050415231PAR1'PAR1' header
-0x0000000450415231PAR1'PAR1' footer (last 4 bytes)

Parquet 形式について

Parquet はテーブルを行単位ではなく列単位で格納します。100 列のうち 3 列しか触らないクエリはその 3 列しか読みませんし、隣り合う値が同じ型で値域も狭いことが多いため、列ごとの圧縮がよく効きます。説明的なもの(スキーマ、行グループ、各カラムチャンクのオフセット・コーデック・最小最大統計)は Thrift の compact protocol でシリアライズされ、データの後ろに書かれます。ファイルが両端で錨を打たれているのはこのためで、オフセット 0 の PAR1 は走査するツールに形式を告げ、末尾の PAR1 は読み手が実際に読み始めるフッターの位置を固定します。

ヘッダーの構造(バイト単位)

オフセット長さフィールド意味
04File magic 'PAR1'4 バイトの 50 41 52 31。ファイルの先頭を走査するツールが形式を名乗れるようにするためだけに存在し、こちら側から他の何かをパースする読み手はいません。フッターを暗号化して書かれたファイルは、ここと末尾の両方が PARE になり、フッターの前に暗号メタデータが来ることを読み手に伝えます。
4variableFirst column chunkデータはマジックナンバーの直後から始まります。符号化された値のページが並び、それぞれ Thrift compact の PageHeader で始まります。先頭にはスキーマもインデックスも行数もないので、Parquet ファイルの最初の 1 MB を見ても中身についてはほとんど何も分かりません。
variablevariableFileMetaData (Thrift compact)スキーマ、行グループ、各カラムチャンクのオフセット・コーデック・エンコーディング・統計。最後の 8 バイトのすぐ前に位置し、読み手はその位置からフッター長を引いて先頭を求めます。オフセット 0 から前方に走査することは決してありません。
-84Footer length直前にある FileMetaData のバイト数を、符号なし 32 ビットのリトルエンディアンで。読み手は末尾 8 バイトへシークしてマジックナンバーを確認し、この数値を読み、その分だけ戻ります。ここが間違っていると、データページがすべて無傷でも致命的です。
-44Trailing magic 'PAR1'オフセット 0 と同じ 4 バイト(フッターが暗号化されていれば PARE)。形式が末尾で錨を打っている以上、どの読み手もまずこのバイト列を確かめます。ヘッダが完璧でも、半分しかダウンロードできていない Parquet が門前払いされるのはそのためです。

似た形式との見分け方

紛らわしい形式見分け方
ORC同じパイプラインに出てくるもう 1 つの列指向形式で、フッターを末尾に置く設計も同じです。ORC は 4 バイトのマジックナンバーではなく 3 バイトの 4F 52 43('ORC')で始まり、最後のバイトはマジックナンバーですらなく postscript の長さ、つまり 256 未満の値が 1 つ入っているだけです。だから末尾 4 バイトを読めば判定できます。PAR1 なら Parquet、意味のない小さな 1 バイトなら ORC です。
Avro OCFAvro のオブジェクトコンテナファイルは同じ取り込みジョブから出てきますが、行指向で自己記述的です。ヘッダは 4 バイトの 4F 62 6A 01('Obj' と 1)、続いて avro.schema と avro.codec を持つメタデータのマップ、そして 16 バイトの同期マーカー。末尾のマジックナンバーが無いので、Avro のファイルは追記しても読めますが、Parquet はそうはいきません。
Encrypted Parquet (PARE)レイアウトは同じで、両端のマジックナンバーだけが違います。PAR1 ではなく PARE。古い読み手が読めない Thrift ではなくマジックナンバーの段階で失敗するよう、意図的にそうしてあります。フッターが暗号化されている場合、末尾マジックナンバーの前の 4 バイトの長さは暗号メタデータと暗号化されたフッターの両方を含むので、同じテーブルでも平文のときより大きな値になります。
SQLite データベースどちらも「分析用のファイル」として渡されますし、どちらも単一ファイルですが、SQLite は行ストアで、マジックナンバーは先頭 16 バイトにあり、末尾のマーカーは一切ありません。オフセット 0 が PAR1 で末尾 4 バイトも PAR1 なら、途中を確認する必要はありません。

よくある壊れ方

  • 末尾の欠落。転送を途中で止めるもの(オブジェクトストレージからのダウンロードの中断、close 前に落ちた書き込みプロセス)は、先頭のマジックナンバーと無傷のページを何 GB も残したまま、フッターだけを書かずに終わります。どのエンジンも「これは Parquet ファイルではない」と報告します。判定しているのが先頭 4 バイトではなく末尾 4 バイトだからです。
  • フッター長が合わなくなっている。Parquet ファイルを 2 つ連結する、1 バイト追記する、エディタが末尾に改行を足す。どれも錨をずらします。末尾のマジックナンバーは PAR1 のままなのに、その前の 4 バイトがページの途中を指すことになり、Thrift のパーサーは「編集された」ではなくゴミを読んだというエラーで落ちます。
  • データページ内の 1 バイト反転。フッターはパースでき、スキーマも列挙でき、壊れたページの直前までは列も正しく読めて、そこで展開器がエラーを出すか値がでたらめにデコードされます。ページごとの CRC は Parquet では省略可能なので、どのページがずれたかを指し示す手掛かりを残さない書き手も多いです。
  • ディレクトリ全体で静かに起きるスキーマのずれ。1 つのファイルの破損ではなく、現実に人がぶつかるほうの障害です。個々のファイルはそれぞれ正当なのに、そのうち 1 つだけある列を int32 として型付けし、他は int64 と言っている。するとクエリエンジンはデータセット全体を拒否します。答えはデータではなく、各ファイルのフッターの中にあります。

この形式の現在地

Parquet は分析の世界における既定のストレージ形式です。Spark、Trino、DuckDB、Polars、pandas、BigQuery のエクスポート、Snowflake のアンロード、どれも読み書きしますし、オブジェクトストレージ上のテーブル形式(Iceberg、Delta Lake、Hudi)は要するに Parquet ファイルのディレクトリとメタデータログの組み合わせです。大きいデータでは CSV を置き換えました。CSV はクエリのたびに端から端まで読み直してパースし直す必要がありますが、Parquet の読み手はフッターを見て、統計から除外できる行グループを捨て、要求された列だけを展開します。今も向いていないのは小さなデータと人が扱う受け渡しです。200 行の対応表は CSV のまま持つほうが楽ですし、1 レコードずつのストリーミング取り込みは Avro の領分です。Parquet のファイルはフッターを書き終えて初めて有効になるからです。

Parquet ファイルをこのサイトで開く

どれもブラウザ内で動きます。ファイルが端末から出ることはありません。

関連する形式

Parquet と混同しやすい形式です。先頭バイトを見比べてください。

形式先頭バイト拡張子
SQLite データベース53 51 4C 69 74 65.sqlite

よくある質問

ファイルのマジックナンバーとは何ですか?

ファイル先頭の数バイトで、名前が何であろうとその形式を示すものです。PNG は必ず 89 50 4E 47 で始まり、ZIP は 50 4B 03 04 で始まります。OS もブラウザも file コマンドも、拡張子を信用せずこのバイト列を読みます。だからファイル名を変えても中身の正体は変わりません。

マジックナンバーを自分で確認する方法は?

macOS や Linux なら xxd -l 16 ファイル名 で先頭 16 バイトが表示されます。Windows なら PowerShell で Format-Hex -Path ファイル名 -Count 16 です。あるいはこのサイトのファイル形式判別ツールにドロップすれば、ローカルでバイト列を読んで形式を教えてくれます。アップロードはありません。

2 つの形式が同じマジックナンバーを持つのはなぜ?

一方が他方の上に作られているからです。docx、xlsx、pptx、apk、jar、epub はすべて中身が ZIP アーカイブなので ZIP の署名で始まり、区別するには内部のエントリを見る必要があります。Java の class ファイルと macOS のユニバーサルバイナリはどちらも CA FE BA BE で始まり、直後のフィールドで見分けます。

マジックナンバーがまったくないファイルもある?

あります。XML、HTML、JSON、SVG、CSV といったテキストベースの形式には固定のバイト署名がないため、構造から判別します。先頭の <?xml 宣言、<svg 要素、あるいは { に続く引用符付きのキーなどです。これは確定ではなく推測なので、このリファレンスではそうした形式をプローブ判別として示しています。

マジックナンバーが一致すればそのファイルは安全?

いいえ。わかるのは形式であって、中身が無害かどうかではありません。正規の PDF や docx でも悪意のあるペイロードを含んでいることがあります。特に拡張子とバイト列が食い違うときに真の形式を知るのは有用な第一段階ですが、マルウェアスキャンではありません。

Parquet かもしれないファイルをお持ちですか?ファイル形式判別ツールで調べる — マジックナンバーをローカルで読み取ります。アップロードは一切ありません。またはすべての形式を見る。