1. 程式人生 > >spark應用提交報錯解決

spark應用提交報錯解決

老樣子,菜雞一隻!如果有什麼說錯的,還請大家見諒~!!也希望大家幫我指出改正。


本次測試的spark版本是2.2.X的,從打包開始,打包有兩種方式,一種是maven打包,一種是idea打包(據說這種打包方式叫SBT?maybe把),然後打出來的包也有兩種,一種叫胖包,一種叫瘦包。我先打了胖包(胖包就是把專案中所有依賴的jar包都打進去,如果依賴多的話,能達到好幾百M,瘦包就是單純打包你的程式碼),然後就開始我的測試之路了!

1、Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

at sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:284)
at sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:238)
at java.util.jar.JarVerifier.processEntry(JarVerifier.java:316)
at java.util.jar.JarVerifier.update(JarVerifier.java:228)

at java.util.jar.JarFile.initializeVerifier(JarFile.java:383)

這種錯誤,是我在老版本(spark-1.6.X)遇到的,這報錯看不懂吧,百度下就好了,很簡單。

解決方式:

在linux中執行命令,其實就是刪除META-INF下面的一些七七八八的東西,具體為什麼,我也不知道

zip -d <你的jar包名稱.jar> META-INF/*.RSA META-INF/*.DSA META-INF/*.SF


2、classnotfound!類似下面這種:



解決方式:


1、有百分之80是你spark-submit指令碼中的--class指定位置有誤,這種時候可以用反編譯工具或者解壓縮工具把你的jar包開啟看看,你的類到底在哪個資料夾裡面,比如說我的類名是Test,一般來說是在com.XXX.XXX.Test

2、測試的時候用的spark2.2的版本,我發現我的路徑沒錯,但還是報了classnotfound,因此我猜測是胖包的問題,所以我打了一個瘦包,一模一樣的指令碼,但是執行成功了,所以我將胖包執行了如上的zip -d XXXX命令,然後解決了這個問題。


3、[Stage 26:=>                                                    (24 + 8) / 1099]

接著我開始執行程式,但是無論我怎麼增加並行度和增加核心數,發現每個stage的並行度永遠只有8???

具體如何增加並行度,其實就是增加分割槽或者設定conf.set("spark.default.parallelism", "500")類似這種方式,但是所有的方式都不生效,後來知道原因的我眼淚掉下來!

1、原因:我發現程式碼中的master(local[*])並沒有註釋掉!因此資料是在本地跑的,為了進一步驗證我的想法,我執行了如下命令:

檢視物理cpu個數
grep 'physical id' /proc/cpuinfo | sort -u
2
檢視核心數量
grep 'core id' /proc/cpuinfo | sort -u | wc -l
4
檢視執行緒數

grep 'processor' /proc/cpuinfo | sort -u | wc -l

8

果然我的並行度最大隻能是8。。。。。

2、解決方式:

把程式碼中的local註釋掉,在指令碼中寫--master yarn  --deploy-mode cluster或者client,我是在測試,所以使用client

4、java.lang.OutOfMemoryError: Java heap space


1、原因:

就是執行的時候JVM記憶體不夠,個人感覺是比如在程式碼中建立物件啊,或者你把資料collect轉換成陣列等型別的操作,又或者資料量大,全部返回到driver端導致的

2、解決方法:

--driver-memory 3G 

通過這種方式加到driver端的記憶體


--conf spark.executor.extraJavaOptions="-XX:MaxPermSize=64m -XX:MaxDirectMemorySize=1536m -Xmn100m" 

通過這種方式設定JVM的引數,比如讓永久代的記憶體變為64M(因為這塊記憶體要用來載入一些底層的類和物件,而且往往是程式關閉前一直要使用的)


5、Exception in thread "main" org.apache.spark.SparkException: Job aborted due to stage failure: Task 30 in stage 31.0 failed 4 times, most recent failure: Lost task 30.3 in stage 31.0 (TID 1998, irs-cdh-40.irs-qb.com, executor 154): ExecutorLostFailure (executor 154 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 5.5 GB of 5.5 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.

1、原因:

這個報錯,看起來就是單個container申請的資源暴增,超過了yarn限制的最大值5.5GB,導致yarn手動把這個container幹掉了。

2、解決方法:

在報錯的最後一句,告訴了我這個考慮下這個引數,這個是設定yarn的堆外記憶體Consider boosting spark.yarn.executor.memoryOverhead.加大這個值,可以避免這個異常,但是佔用的資源就比較多

與之對應的引數是-XX:MaxDirectMemorySize(可以調小這個值,讓堆內進行GC,不過也不能太小,否則會報Direct buffer memory異常)

3、建議:

遇到這個報錯,還是把GC的資訊打印出來看看,看看記憶體的佔用是什麼情況,選擇增大第一個值還是減小第二個值

具體設定可以參考(無名氏0428)大神的文章:https://blog.csdn.net/ainidong2005/article/details/53152605

6、最後就是資源的調整

一開始設定的每個exe核心數和記憶體較多,發現資源申請不下來,導致程式比單機還慢,因此轉換策略,將每個executor的資源調小,然後申請更多的executor來處理資料,果然申請到資源了,而且效果顯著,最後指令碼如下

/XXX/XXXX/XXX/bin/spark2-submit \
--master yarn \
--deploy-mode client \
--executor-memory 2G \
--driver-memory 3G \
--num-executors 20 \
--executor-cores 1 \
--conf spark.yarn.executor.memoryOverHead=2048 \
--conf spark.executor.extraJavaOptions="-XX:MaxPermSize=64m -XX:MaxDirectMemorySize=1536m -Xmn100m" \
--class com.XXX.XXX.XXX \
/home/XXX/XXX.jar


額,其實對於JVM中的各塊記憶體的設定,本人還不是特別的清晰,不知是否有大神寫出相關的軟文,可以推薦下,讓我學習學習,本文純屬個人心路歷程,如果有什麼說的不對的地方,還請大家指出改正!