web-dev-qa-db-ja.com

SparkはS3の寄木細工のファイルの真の列スキャンをサポートしていますか?

Parquetデータストレージ形式の大きな利点の1つは、 列型 であるということです。数百の列を持つ「幅の広い」データセットがあるが、クエリがそれらのいくつかにしか触れていない場合、それらのいくつかの列を格納するデータのみを読み取り、残りをスキップすることができます。

おそらく、この機能は、各列のファイルシステム上の場所を示す寄木細工のファイルの先頭にあるメタデータのビットを読み取ることによって機能します。その後、リーダーはディスク上で必要な列のみを読み取るようにシークできます。

Sparkのデフォルトの寄木細工のリーダーがS3でこの種の選択的シークを正しく実装しているかどうかを誰かが知っていますか? S3でサポートされています と思いますが、理論的なサポートと、そのサポートを適切に活用する実装には大きな違いがあります。

32
conradlee

これは分解する必要があります

  1. 寄木細工のコードはspark(yes)から述語を取得しますか
  2. 次に、寄木細工の床は、Hadoop FileSystemseek() + read()またはreadFully(position, buffer, length)呼び出しを使用して、これらの列のみを選択的に読み取ろうとしますか?はい
  3. S3コネクタはこれらのファイル操作を効率的なHTTPGETリクエストに変換しますか? Amazon EMRの場合:はい。 Apache Hadoopでは、クラスパスにhadoop 2.8が必要であり、ランダムアクセスをトリガーするように適切に_spark.hadoop.fs.s3a.experimental.fadvise=random_を設定する必要があります。

Hadoop 2.7以前は、ファイルのラウンドでアグレッシブなseek()を適切に処理しません。これは、ファイルのGETオフセット終了を常に開始し、次のシークに驚いて、その接続を中止し、新しいTCP/HTTPS1.1接続を再度開く必要があるためです。 (遅い、CPUが重い)、もう一度繰り返します。ランダムなIO操作は、.csv.gzなどの一括読み込みでは問題がありますが、ORC /寄木細工のパフォーマンスを取得するには重要です。

Hadoop2.7のhadoop-awsJARではスピードアップは得られません。必要な場合は、hadoop * .jarと依存関係を更新するか、Hadoop2.8に対してSparkをゼロから構築する必要があります)

Hadoop 2.8+にもちょっとした機能があることに注意してください。ログステートメントでS3AファイルシステムクライアントでtoString()を呼び出すと、すべてのファイルシステムIO stats、シークで破棄されたデータの量を含め、中止されたTCP接続&c。何が起こっているのかを理解するのに役立ちます。

2018-04-13警告::Hadoop 2.8+ _hadoop-aws_ JARを残りのhadoop-2.7JARセットと一緒にクラスパスにドロップしようとしないでください。スピードアップが見られると期待してください。 。表示されるのはスタックトレースだけです。すべてのHadoopJARとそれらの推移的な依存関係を更新する必要があります。

10
Steve Loughran

免責事項:私には明確な答えはなく、信頼できる情報源としても行動したくありませんが、Spark 2.2+で寄木細工のサポートに時間を費やしており、私の答えを期待しています私たち全員が正しい答えに近づくのを助けることができます。


S3のParquetは、S3から未使用の列のデータをプルすることを避け、必要なファイルチャンクのみを取得しますか、それともファイル全体をプルしますか?

今日作成したSpark2.3.0-SNAPSHOT)を使用します master

parquetデータソース形式は ParquetFileFormat によって処理されます。これは FileFormat です。

正しければ、読み取り部分は buildReaderWithPartitionValues メソッド(FileFormatをオーバーライドします)によって処理されます。

buildReaderWithPartitionValuesは、FileSourceScanExecが実行されたときに内部行を生成するために、実際には単一のRDDであるいわゆる入力RDDに対してWholeStageCodegenExec物理演算子が要求された場合にのみ使用されます。

そうは言っても、buildReaderWithPartitionValuesの機能を確認することで、最終的な答えに近づくことができると思います。

を見ると、私たちが正しい方向に進んでいることが保証されます。

//フィルタのプッシュダウンが有効になっているときに、フィルタをプッシュダウンしようとします。

そのコードパスは、spark.sql.parquet.filterPushdown Sparkプロパティ デフォルトでオンになっています )に依存します。

spark.sql.parquet.filterPushdowntrueに設定すると、Parquetフィルターのプッシュダウン最適化が有効になります。

これにより、parquet-hadoopの ParquetInputFormat.setFilterPredicateiffフィルターが定義されます。

if (pushed.isDefined) {
  ParquetInputFormat.setFilterPredicate(hadoopAttemptContext.getConfiguration, pushed.get)
}

コードが(いわゆるベクトル化された寄木細工のデコードリーダーを使用するのではなく)parquet-mrにフォールバックするときにフィルターが使用されると、コードは少し後でより興味深いものになります。それは私が本当に理解していない部分です(コードで見ることができるものを除いて)。

ベクトル化された寄木細工のデコードリーダーは、デフォルトでオンになっているspark.sql.parquet.enableVectorizedReader Sparkプロパティによって制御されることに注意してください。

ヒント:if式のどの部分が使用されているかを知るには、org.Apache.spark.sql.execution.datasources.parquet.ParquetFileFormatロガーのDEBUGログレベルを有効にします。

プッシュダウンされたすべてのフィルターを表示するには、org.Apache.spark.sql.execution.FileSourceScanExecロガーのINFOログレベルをオンにします。 ログで以下を参照

INFO Pushed Filters: [pushedDownFilters]

それが決定的な答えに近くない場合、それが少し助けになり、誰かが私が中断したところからそれを拾い上げてすぐにそれを作ることを願っています。 希望は最後に死ぬ:)

8
Jacek Laskowski

いいえ、述語プッシュダウンは完全にはサポートされていません。もちろん、これは以下に依存します。

  • 特定のユースケース
  • Sparkバージョン
  • S3コネクタのタイプとバージョン

特定のユースケースを確認するために、SparkでDEBUGログレベルを有効にして、クエリを実行できます。次に、S3(HTTP)リクエスト中に「シーク」があるかどうか、および実際に送信されたリクエストの数を確認できます。このようなもの:

_17/06/13 05:46:50 DEBUG wire: http-outgoing-1 >> "GET /test/part-00000-b8a8a1b7-0581-401f-b520-27fa9600f35e.snappy.parquet HTTP/1.1[\r][\n]" .... 17/06/13 05:46:50 DEBUG wire: http-outgoing-1 << "Content-Range: bytes 0-7472093/7472094[\r][\n]" .... 17/06/13 05:46:50 DEBUG wire: http-outgoing-1 << "Content-Length: 7472094[\r][\n]"_

以下は、Parquetファイルに保存されているメタデータに基づいてデータセット内のすべての行のCOUNT(*)を計算できないSpark 2.1)が原因で最近開かれた問題レポートの例です。 https://issues.Apache.org/jira/browse/SPARK-21074

1
Michael Spector

sparkの寄木細工のリーダーは、他のInputFormatとまったく同じです。

  1. InputFormatには、S3に特別なものはありません。入力フォーマットは、LocalFileSystem、Hdfs、およびS3から読み取ることができ、特別な最適化は行われません。

  2. 要求する列に応じて寄木細工のInpuTFormatは、選択的に列を読み取ります。

  3. 確実に(プッシュダウン述語は最新のsparkバージョンで機能しますが)

0
KrazyGautam