我們自己編寫了spark代碼后;放到集群中一執行,就會出現問題,沒有序列化、指定的配置文件不存在、classnotfound等等。這其實很多時候就是因為我們對自己編寫的spark代碼執行流程的不熟悉導致的,源碼閱讀可以解決,但源碼不是每個人都能看懂或能看進去的,下面我們就來講一下,我們自己寫的spark代碼究竟是這么執行的。從執行的過程可分為三個部分來分析main方法,RDD處理方法,DStream處理方法,從執行的JVM虛擬機可以分為兩個部分driver端,worker端
(架構師之路③群:256909960,歡迎加入)
一、main方法
main方法就是在driver端執行的,當然這里是把RDD計算的Action剔除的情況,先看一段代碼

1、driver端
除了rdd算子中的代碼其他都是在driver端執行,並且只執行一次
(架構師之路③群:256909960,歡迎加入)
2、worker端
DSUtil.dSopt()這里的帶就是處理DSTream的,其中有一部分代碼是driver一部分是Worker的,這里姑且認為是在worker端
(架構師之路③群:256909960,歡迎加入)
二、DStream處理方法
在sparkStreaming中spark引入了DStream,實際上就是RDD的map集合(不是很精確),在處理的時候代碼是:

(架構師之路③群:256909960,歡迎加入)
1、driver端
除了Dstram計算中的代碼其他都是在driver端並且只執行一次。
這里需要注意的是DStream的action方法(閉包)中的代碼也不是全在worker端執行,只有在處理rdd時才會在Worker端執行,其他是在driver端執行的;
與DStream的算子方法外的代碼區別是,這里是計算一次執行一次。
(架構師之路③群:256909960,歡迎加入)
2、worker端
rdd的Action操作(閉包)中的代碼都是在Worker端執行的
(架構師之路③群:256909960,歡迎加入)
三、RDD處理方法
最后我們來看看RDD算子閉包在執行時代碼如何執行

(架構師之路③群:256909960,歡迎加入)
1、driver端
擋在調用count方法處理rdd時,與rdd算子無關的代碼都是計算一次執行一次
(架構師之路③群:256909960,歡迎加入)
2、worker端
rdd的算子閉包是在driver端中執行的
(架構師之路③群:256909960,歡迎加入)
四、總結
根據spark中job的生成過程,來看代碼執行就一目了然了,spark中job的生成是在driver端,這里只是生成了一個模板,並不會在driver端執行,spark會把這個模板及與模板相關的對象一起發送到worker端(這就是移動計算不移動數據,與storm的區別),Worker有了數據和模板就可以計算了,Worker會從Action算子開始向上逆推在計算,這樣就有了Rdd算子代碼在worker端執行;
但是這里ForeachRDD,transformRDD中的代碼怎么又在driver端執行了?
這是因為spark一開始生成的是一個靜態模板在spark每個batch執行計算式,會用這個靜態的模板動態生成以DAG,所以就有了DStream中的算子代碼在driver中執行
(架構師之路③群:256909960,歡迎加入)