web-dev-qa-db-ja.com

Sparkの高速寄木細工の行数

Parquetファイルには、ブロックごとの行数フィールドが含まれています。 Sparkはある時点でそれを読んでいるようです( SpecificParquetRecordReaderBase.Java#L151 )。

私はこれをspark-Shellで試しました:

sqlContext.read.load("x.parquet").count

そして、Sparkは2つのステージを実行し、DAGでのさまざまな集約ステップを示しました。これは、行数を使用する代わりに、通常どおりファイルを読み取ることを意味すると思います。 (私は間違っている可能性があります。)

質問は次のとおりです。countを実行すると、Sparkはすでに行数フィールドを使用していますか?それらのフィールドを使用する別のAPIはありますか?これらのフィールドに依存することは、何らかの理由で悪い考えですか?

11
Daniel Darabos

正解です。countを実行しているとき、Sparkはすでにrowcountsフィールドを使用しています。

詳細を少し掘り下げて、 SpecificParquetRecordReaderBase.Javaフラットスキーマコミットを使用する場合のParquetスキャンパフォーマンスの向上 の一部として [SPARK-11787]スピードアップフラットスキーマ用の寄木細工のリーダー 。このコミットはSpark 1.6ブランチの一部として含まれていることに注意してください。

クエリが行数の場合、説明したとおりに機能します(つまり、メタデータを読み取ります)。述語が最小/最大値によって完全に満たされている場合、そのも機能するはずですが、完全には検証されていません。これらのParquetフィールドを使用することは悪い考えではありませんが、前のステートメントで暗示されているように、重要な問題は、述語フィルタリングがメタデータと一致することを確認して、正確なカウントを行うことです。

2つの段階がある理由を理解しやすくするために、count()ステートメントの実行時に作成されるDAGを次に示します。

enter image description here

2つのステージを掘り下げるときは、最初のステージ(ステージ25)がファイルスキャンを実行し、2番目のステージ(ステージ26)がカウントのシャッフルを実行していることに注意してください。

enter image description hereenter image description here

検証してくれたNongLi( SpecificParquetRecordReaderBase.Java commitの作成者)に感謝します!

更新しました

_Dataset.count_とParquetの間のブリッジに追加のコンテキストを提供するために、これを取り巻く内部ロジックのフローは次のとおりです。

  • Sparkは、カウントを計算するために寄木細工の列を読み取りません
  • ParquetスキーマをVectorizedParquetRecordReaderに渡すことは、実際には空のParquetメッセージです。
  • Parquetファイルフッターに保存されているメタデータを使用してカウントを計算します。 InternalRow.scala ごとにInternalRowを返すイテレータ内で上記をラップする必要があります。

寄木細工のファイル形式を内部的に操作するために、Apache Sparkは、InternalRowを返すイテレーターでロジックをラップします。詳細については、 InternalRow.scala)を参照してください。 。最終的に、count()集計関数は、このイテレーターを使用して、基になるParquetデータソースと対話します。ところで、これは、ベクトル化されたParquetリーダーとベクトル化されていないParquetリーダーの両方に当てはまります。

したがって、Dataset.count()をParquetリーダーとブリッジするためのパスは次のとおりです。

  • Dataset.count()呼び出しは、単一のcount()集計関数を持つ集計演算子に計画されています。
  • Javaコードは、集計演算子とcount()集計関数の計画時に生成されます。
  • 生成されたJavaコードは、SparkデータソースAPIによって内部的に使用されるRecordReaderIteratorを使用して、基になるデータソースParquetFileFormatと対話します。

詳細については、 寄木細工の数のメタデータの説明 を参照してください。

13
Denny Lee