Applications
一個(gè)spark Application由一個(gè)或多個(gè)job組成窃诉。
Jobs
一個(gè)job是由一個(gè)或多個(gè)stage組成的。對(duì)RDD每次執(zhí)行一個(gè)action操作被饿,都會(huì)觸發(fā)提交一個(gè)job。
Stages
一個(gè)stage由一個(gè)或多個(gè)task組成禽捆。RDD經(jīng)過一系列的轉(zhuǎn)換會(huì)生成一個(gè)DAG藐石,spark會(huì)根據(jù)寬依賴(wide dependency)將DAG劃分為不同的stage。
Tasks
一個(gè)task負(fù)責(zé)處理RDD一個(gè)partition的數(shù)據(jù)吨悍。一個(gè)stage內(nèi)部會(huì)啟動(dòng)多個(gè)task扫茅。
樣例分析
在spark上運(yùn)行如下代碼
object SimpleApp {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("Simple Application")
val sc = new SparkContext(conf)
val rddA = sc.textFile("/tmp/xyx/textA")
val rddB = sc.textFile("/tmp/xyx/textB")
val rddAA = rddA.flatMap(line => line.split(",")).map(word => (word, 1))
val rddBB = rddB.flatMap(line => line.split(",")).map(word => (word, 1))
val rddAAA = rddAA.groupByKey(1)
val rddBBB = rddBB.groupByKey(1)
val rddC = rddAAA.join(rddBBB)
rddC.count
rddC.collect
sc.stop()
}
}
代碼中運(yùn)行了兩個(gè)RDD的action(count
和collect
),所以這個(gè)spark的Application會(huì)啟動(dòng)2個(gè)job育瓜,如下圖
可以看到每個(gè)job都是由3個(gè)stage組成的葫隙,只不過它們的前兩個(gè)stage完全一樣,所以Job 1的狀態(tài)是skipped躏仇。
那么為什么是3個(gè)stage恋脚,是怎么劃分的?
這就要看一下上面代碼中RDD的轉(zhuǎn)換有哪些是寬依賴焰手,即
groupByKey
和join
糟描。那么從rddA轉(zhuǎn)換為rddAA是一個(gè)stage,rddB轉(zhuǎn)換為rddBB是一個(gè)stage书妻,最后上面兩個(gè)stage的結(jié)果rddAAA和rddBBB到rddC為一個(gè)stage船响,一共3個(gè)stage。
進(jìn)入到Job 0中,如下圖见间,看一下具體的3個(gè)stage聊闯,每個(gè)stage里面啟動(dòng)了多個(gè)task。