[英]Why so many tasks in my spark job? Getting 200 Tasks By Default
我有一個spark作業,它接收來自hdfs的8條記錄的文件,做一個簡單的聚合並將其保存回hdfs。 當我這樣做時,我注意到有數百個任務。
我也不確定為什么有這么多工作? 我覺得工作更像是一個動作發生的時候。 我可以推測為什么 - 但我的理解是,在這段代碼中它應該是一個工作,它應該分解為階段,而不是多個工作。 為什么不把它分解成各個階段,為什么它會闖入工作崗位?
至於200多個任務,由於數據量和節點數量微乎其微,當只有一個聚合和幾個過濾器時,每行數據有25個任務是沒有意義的。 為什么每個原子操作每個分區只有一個任務?
這是相關的scala代碼 -
import org.apache.spark.sql._
import org.apache.spark.sql.types._
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
object TestProj {object TestProj {
def main(args: Array[String]) {
/* set the application name in the SparkConf object */
val appConf = new SparkConf().setAppName("Test Proj")
/* env settings that I don't need to set in REPL*/
val sc = new SparkContext(appConf)
val sqlContext = new SQLContext(sc)
import sqlContext.implicits._
val rdd1 = sc.textFile("hdfs://node002:8020/flat_files/miscellaneous/ex.txt")
/*the below rdd will have schema defined in Record class*/
val rddCase = sc.textFile("hdfs://node002:8020/flat_files/miscellaneous/ex.txt")
.map(x=>x.split(" ")) //file record into array of strings based spaces
.map(x=>Record(
x(0).toInt,
x(1).asInstanceOf[String],
x(2).asInstanceOf[String],
x(3).toInt))
/* the below dataframe groups on first letter of first name and counts it*/
val aggDF = rddCase.toDF()
.groupBy($"firstName".substr(1,1).alias("firstLetter"))
.count
.orderBy($"firstLetter")
/* save to hdfs*/
aggDF.write.format("parquet").mode("append").save("/raw/miscellaneous/ex_out_agg")
}
case class Record(id: Int
, firstName: String
, lastName: String
, quantity:Int)
}
下面是單擊具有200多個任務的舞台時屏幕的第一部分
根據要求,這里是工作ID 1的階段
以下是具有200個任務的作業ID 1中的階段的詳細信息
這是一個經典的Spark問題。
用於讀取的兩個任務(第二個圖中的階段Id 0)是defaultMinPartitions
設置,它設置為2.您可以通過讀取REPL sc.defaultMinPartitions
的值來獲取此參數。 它也應該在“環境”選項卡下的Spark UI中可見。
你可以看一下GitHub中的代碼 ,看看這到底發生了什么。 如果您希望在讀取時使用更多分區,只需將其添加為參數,例如sc.textFile("a.txt", 20)
。
現在有趣的部分來自第二階段出現的200個分區(第二個階段的階段Id 1)。 好吧,每次有一個shuffle,Spark需要決定shuffle RDD有多少個分區。 可以想象,默認值為200。
您可以使用以下方法更改:
sqlContext.setConf("spark.sql.shuffle.partitions", "4”)
如果使用此配置運行代碼,您將看到200個分區不再存在。 如何設置此參數是一種藝術。 也許選擇2倍的核心數量(或其他)。
我認為Spark 2.0有一種方法可以自動推斷shuffle RDD的最佳分區數。 期待那樣!
最后,您獲得的作業數量與生成的優化Dataframe代碼產生的RDD操作數量有關。 如果您閱讀Spark規范,它會說每個RDD操作都會觸發一個作業。 當您的操作涉及Dataframe或SparkSQL時,Catalyst優化器將找出執行計划並生成一些基於RDD的代碼來執行它。 在你的情況下,很難確切地說它為什么會使用兩個動作。 您可能需要查看優化的查詢計划,以確切了解正在執行的操作。
我有個類似的問題。 但在我的場景中,我並行化的集合比Spark計划的任務數量少(導致火花有時奇怪地表現)。 使用強制分區號我能解決這個問題。
它是這樣的:
collection = range(10) # In the real scenario it was a complex collection
sc.parallelize(collection).map(lambda e: e + 1) # also a more complex operation in the real scenario
然后,我在Spark日志中看到:
INFO YarnClusterScheduler: Adding task set 0.0 with 512 tasks
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.