您好,登錄后才能下訂單哦!
Spark閉包中driver及executor程序代碼是怎樣執(zhí)行的,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
閉包的作用可以理解為:函數(shù)可以訪問函數(shù)外部定義的變量,但是函數(shù)內(nèi)部對該變量進(jìn)行的修改,在函數(shù)外是不可見的,即對函數(shù)外源變量不會產(chǎn)生影響。
其實,在學(xué)習(xí)Spark時,一個比較難理解的點就是,在集群模式下,定義的變量和方法作用域的范圍和生命周期。這在你操作RDD時,比如調(diào)用一些函數(shù)map、foreach時,訪問其外部變量進(jìn)行操作時,很容易產(chǎn)生疑惑。為什么我本地程序運(yùn)行良好且結(jié)果正確,放到集群上卻得不到想要的結(jié)果呢?
但是在生產(chǎn)中,我們的任務(wù)都是在集群模式下運(yùn)行,如何能滿足這種業(yè)務(wù)場景呢?
這就必須引出一個后續(xù)要重點講解的概念:Accumulator即累加器。Spark中的累加器專門用于提供一種機(jī)制,用于在集群中的各個worker節(jié)點之間執(zhí)行時安全地更新變量。
首先,對RDD相關(guān)的操作需要傳入閉包函數(shù),如果這個函數(shù)需要訪問外部定義的變量,就需要滿足一定條件(比如必須可被序列化),否則會拋出運(yùn)行時異常。閉包函數(shù)在最終傳入到executor執(zhí)行,需要經(jīng)歷以下步驟:
1.driver通過反射,運(yùn)行時找到閉包訪問的變量,并封裝成一個對象,然后序列化該對象
2.將序列化后的對象通過網(wǎng)絡(luò)傳輸?shù)絯orker節(jié)點
3.worker節(jié)點反序列化閉包對象
4.worker節(jié)點的executor執(zhí)行閉包函數(shù)
driver是運(yùn)行用戶編寫Application 的main()函數(shù)的地方,具體負(fù)責(zé)DAG的構(gòu)建、任務(wù)的劃分、task的生成與調(diào)度等。job,stage,task生成都離不開rdd自身,rdd的相關(guān)的操作不能缺少driver端的sparksession/sparkcontext。
最后做個總結(jié):所有對RDD具體數(shù)據(jù)的操作都是在executor上執(zhí)行的,所有對rdd自身的操作都是在driver上執(zhí)行的。比如foreach、foreachPartition都是針對rdd內(nèi)部數(shù)據(jù)進(jìn)行處理的,所以我們傳遞給這些算子的函數(shù)都是執(zhí)行于executor端的。但是像foreachRDD、transform則是對RDD本身進(jìn)行一列操作,所以它的參數(shù)函數(shù)是執(zhí)行在driver端的,那么它內(nèi)部是可以使用外部變量,比如在SparkStreaming程序中操作offset、動態(tài)更新廣播變量等。
關(guān)于Spark閉包中driver及executor程序代碼是怎樣執(zhí)行的問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。