Parquetは主にHadoopのエコシステムで使われるカラムナフォーマット。 CSVのようなrow-basedのフォーマットと比べて不必要なカラムを読まずに済み、また行に関しても絞るための仕組みがあるので効率的にクエリを実行することができる。
フォーマット

行はいくつかのRow Groupに水平分割され、その中に各カラムのColumn Chunkが順に並んでいる。Column ChunkはさらにPageに分けられ、その単位で圧縮やエンコーディングが行われる。
一方向にファイルを書き込めるようにRowGroupの後にメタデータが来るようになっている。
ネストしたスキーマにも対応していて、フラットにした後にRepetiton LevelとDefinition Levelで繰り返しや階層を表している。
Readの最適化
ColumnMetadataにレコード数や最小最大値、圧縮コーデックやサイズが含まれているため、Readerは必要なものだけを展開して読むことができる。 したがって取得するカラムを絞ったり、フィルタに用いるカラムをソートしておくと読むPageを減らすことができる。
メタデータの例
公式のCLIツールであるparquet-cliで実ファイルのメタデータを見てみる。
parquet-tools
というのもあるがすでにdeprecatedになっておりリポジトリからも消えている。
$ brew install parquet-cli
AWS Glueでjsonから変換したparquetを対象としている。
$ cat test.json
{"A":"aaaa","B":["b"],"C":{"D":10}}
$ parquet meta test.parquet
File path: test.parquet
Created by: parquet-glue version 1.8.2
Properties:
org.apache.spark.sql.parquet.row.metadata: {"type":"struct","fields":[{"name":"A","type":"string","nullable":true,"metadata":{}},{"name":"B","type":{"type":"array","elementType":"string","containsNull":true},"nullable":true,"metadata":{}},{"name":"C","type":{"type":"struct","fields":[{"name":"D","type":"integer","nullable":true,"metadata":{}}]},"nullable":true,"metadata":{}}]}
Schema:
message glue_schema {
optional binary A (STRING);
optional group B (LIST) {
repeated group list {
optional binary element (STRING);
}
}
optional group C {
optional int32 D;
}
}
Row group 0: count: 1 216.00 B records start: 4 total: 216 B
--------------------------------------------------------------------------------
type encodings count avg size nulls min / max
A BINARY G _ 1 76.00 B 0 "aaaa" / "aaaa"
B.list.element BINARY G _ 1 66.00 B 0 "b" / "b"
C.D INT32 G _ 1 74.00 B 0 "10" / "10"