這篇文章給大家介紹Spark作業(yè)的原理是什么,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
為紹興等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及紹興網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、紹興網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
YARN集群管理器會(huì)根據(jù)我們?yōu)镾park作業(yè)設(shè)置的資源參數(shù),在各個(gè)工作節(jié)點(diǎn)上,啟動(dòng)一定數(shù)量的Executor進(jìn)程,每個(gè)Executor進(jìn)程都占有一定數(shù)量的內(nèi)存和CPUcore。
在申請(qǐng)到了作業(yè)執(zhí)行所需的資源之后,Driver進(jìn)程就會(huì)開始調(diào)度和執(zhí)行我們編寫的作業(yè)代碼了。
Driver進(jìn)程會(huì)將我們編寫的Spark作業(yè)代碼分拆為多個(gè)stage,每個(gè)stage執(zhí)行一部分代碼片段,并為每個(gè)stage創(chuàng)建一批task,然后將這些task分配到各個(gè)Executor進(jìn)程中執(zhí)行。
task是最小的計(jì)算單元,負(fù)責(zé)執(zhí)行一模一樣的計(jì)算邏輯(也就是我們自己編寫的某個(gè)代碼片段),只是每個(gè)task處理的數(shù)據(jù)不同而已。
一個(gè)stage的所有task都執(zhí)行完畢之后,會(huì)在各個(gè)節(jié)點(diǎn)本地的磁盤文件中寫入計(jì)算中間結(jié)果,然后Driver就會(huì)調(diào)度運(yùn)行下一個(gè)stage。
下一個(gè)stage的task的輸入數(shù)據(jù)就是上一個(gè)stage輸出的中間結(jié)果。如此循環(huán)往復(fù),直到將我們自己編寫的代碼邏輯全部執(zhí)行完,并且計(jì)算完所有的數(shù)據(jù),得到我們想要的結(jié)果為止。
Spark是根據(jù)shuffle類算子來進(jìn)行stage的劃分。如果我們的代碼中執(zhí)行了某個(gè)shuffle類算子(比如reduceByKey、join等),那么就會(huì)在該算子處,劃分出一個(gè)stage界限來。
可以大致理解為,shuffle算子執(zhí)行之前的代碼會(huì)被劃分為一個(gè)stage,shuffle算子執(zhí)行以及之后的代碼會(huì)被劃分為下一個(gè)stage。
因此一個(gè)stage剛開始執(zhí)行的時(shí)候,它的每個(gè)task可能都會(huì)從上一個(gè)stage的task所在的節(jié)點(diǎn),去通過網(wǎng)絡(luò)傳輸拉取需要自己處理的所有key,然后對(duì)拉取到的所有相同的key使用我們自己編寫的算子函數(shù)執(zhí)行聚合操作(比如reduceByKey()算子接收的函數(shù))。這個(gè)過程就是shuffle。
當(dāng)我們?cè)诖a中執(zhí)行了cache/persist等持久化操作時(shí),根據(jù)我們選擇的持久化級(jí)別的不同,每個(gè)task計(jì)算出來的數(shù)據(jù)也會(huì)保存到Executor進(jìn)程的內(nèi)存或者所在節(jié)點(diǎn)的磁盤文件中。
因此Executor的內(nèi)存主要分為三塊:
第一塊是讓task執(zhí)行我們自己編寫的代碼時(shí)使用,默認(rèn)是占Executor總內(nèi)存的20%;
第二塊是讓task通過shuffle過程拉取了上一個(gè)stage的task的輸出后,進(jìn)行聚合等操作時(shí)使用,默認(rèn)也是占Executor總內(nèi)存的20%;
第三塊是讓RDD持久化時(shí)使用,默認(rèn)占Executor總內(nèi)存的60%。
task的執(zhí)行速度是跟每個(gè)Executor進(jìn)程的CPUcore數(shù)量有直接關(guān)系的。一個(gè)CPUcore同一時(shí)間只能執(zhí)行一個(gè)線程。而每個(gè)Executor進(jìn)程上分配到的多個(gè)task,都是以每個(gè)task一條線程的方式,多線程并發(fā)運(yùn)行的。
如果CPUcore數(shù)量比較充足,而且分配到的task數(shù)量比較合理,那么通常來說,可以比較快速和高效地執(zhí)行完這些task線程。
關(guān)于Spark作業(yè)的原理是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。