spark 1.6.1を使用します。
私のsparkアプリケーションは、s3に保存されている10000を超える寄木細工のファイルを読み取ります。
val df = sqlContext.read.option("mergeSchema", "true").parquet(myPaths: _*)
myPaths
はArray[String]
には、10000の寄木細工のファイルのパスが含まれています。各パスは次のようですs3n://bucketname/blahblah.parquet
Sparkは以下のようなメッセージを警告します。
警告TaskSetManager:ステージ4には非常に大きなサイズ(108KB)のタスクが含まれています。タスクの最大推奨サイズは100KBです。
とにかくSparkはジョブを実行して完了しましたが、これによりsparkジョブの処理が遅くなる可能性があります。
誰かがこの問題について良い提案をしていますか?
問題は、データセットがパーティション間で均等に分散されていないため、一部のパーティションは他のパーティションよりも多くのデータを持っていることです(したがって、一部のタスクはより大きな結果を計算します)。
デフォルトでは、Spark SQLはspark.sql.shuffle.partitions
プロパティを使用して200のパーティションを想定しています( その他の構成オプション を参照):
spark.sql.shuffle.partitions(デフォルト:200)結合または集計のためにデータをシャッフルするときに使用するパーティションの数を構成します。
解決策は、寄木細工のファイルを読み取った後(アクションを実行する前)にデータセットをcoalesce
またはrepartition
することです。
explain
またはWeb UIを使用して、実行計画を確認します。
警告はクエリを最適化するためのヒントを提供するため、より効果的な結果フェッチが使用されます( TaskSetManager を参照)。
警告付き(ドライバーで実行される)TaskSchedulerは、効果の低いアプローチIndirectTaskResult
を使用して結果値をフェッチします( コード で確認できます)。