web-dev-qa-db-ja.com

Spark失敗:原因:org.Apache.spark.shuffle.FetchFailedException:大きすぎるフレーム:5454002341

親子を決定するテーブルの階層を生成しています。

大きすぎるフレームに関するエラーが発生した後でも、以下の構成が使用されています。

スパークプロパティ

--conf spark.yarn.executor.memoryOverhead=1024mb \
--conf yarn.nodemanager.resource.memory-mb=12288mb \
--driver-memory 32g \
--driver-cores  8 \
--executor-cores 32 \
--num-executors 8 \
--executor-memory 256g \
--conf spark.maxRemoteBlockSizeFetchToMem=15g

import org.Apache.log4j.{Level, Logger};
import org.Apache.spark.SparkContext;
import org.Apache.spark.sql.{DataFrame, SparkSession};
import org.Apache.spark.sql.functions._;
import org.Apache.spark.sql.expressions._;


lazy val sparkSession = SparkSession.builder.enableHiveSupport().getOrCreate();

import spark.implicits._;

val hiveEmp: DataFrame = sparkSession.sql("select * from db.employee");
hiveEmp.repartition(300);
import org.Apache.spark.sql.functions._;

val nestedLevel = 3;

val empHierarchy = (1 to nestedLevel).foldLeft(hiveEmp.as("wd0")) { (wDf, i) =>
val j = i - 1
wDf.join(hiveEmp.as(s"wd$i"), col(s"wd$j.parent_id".trim) === col(s"wd$i.id".trim), "left_outer")
}.select(
col("wd0.id") :: col("wd0.parent_id") ::
col("wd0.amount").as("amount") :: col("wd0.payment_id").as("payment_id") :: (
(1 to nestedLevel).toList.map(i => col(s"wd$i.amount").as(s"amount_$i")) :::
(1 to nestedLevel).toList.map(i => col(s"wd$i.payment_id").as(s"payment_id_$i"))

): _*);

empHierarchy.write.saveAsTable("employee4");

エラー

Caused by: org.Apache.spark.SparkException: Task failed while writing rows
   at org.Apache.spark.sql.execution.datasources.FileFormatWriter$.org$Apache$spark$sql$execution$datasources$FileFormatWriter$$executeTask(FileFormatWriter.scala:204)
   at org.Apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$write$1$$anonfun$3.apply(FileFormatWriter.scala:129)
   at org.Apache.spark.sql.execution.datasources.FileFormatWriter$$anonfun$write$1$$anonfun$3.apply(FileFormatWriter.scala:128)
   at org.Apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:87)
   at org.Apache.spark.scheduler.Task.run(Task.scala:99)
   at org.Apache.spark.executor.Executor$TaskRunner.run(Executor.scala:322)
   ... 3 more
Caused by: org.Apache.spark.shuffle.FetchFailedException: Too large frame: 5454002341
   at org.Apache.spark.storage.ShuffleBlockFetcherIterator.throwFetchFailedException(ShuffleBlockFetcherIterator.scala:361)
   at org.Apache.spark.storage.ShuffleBlockFetcherIterator.next(ShuffleBlockFetcherIterator.scala:336)
3
Sampat Kumar

数年分のデータをバックフィルしようとすると、まったく同じエラーが発生しました。結局のところ、パーティションのサイズが2GBより大きいためです。

  1. (repartition()を使用して)パーティション数を増やして、パーティションが2GB未満になるようにすることもできます。 (パーティションを128 mbから256 mbに、つまりHDFSブロックサイズに近づけます)

  2. または、上記のようにシャッフルの制限を2GB以上に増やすことができます。 (それを避けてください)。また、大量のデータを含むパーティションでは、タスクが終了するまでに長い時間がかかります。

注:repartition(n)を実行すると、s3/hdfsへの書き込み中にパーティションごとにnのパーツファイルが生成されます。

詳細については、こちらをお読みください: http://www.russellspitzer.com/2018/05/10/SparkPartitions/

1
Prasad Sogalad