Spark任務報java.lang.StackOverflowError

Spark任務報java.lang.StackOverflowError

簡介

日前遇到一個問題,在提交一個spark任務(提交模式:yarn-client),去讀取2000+個字段的hive表時,報出一個錯誤:java.lang.StackOverflowError,於此分析記錄一下問題。

問題分析

此問題的原因在於,通過sparksession去讀取hive表時,會在 driver 端去解析語法樹,和SQL執行計劃,由於字段過多,產生大量引用,佔用較多棧空間,而默認情況下,Java棧空間只有1M大小,因此報錯了。

幾點需要明確的

1.首先明確,解析語法樹,是在driver端,報錯也是driver報的,與executor沒有什麼關係,因此,需要修改的配置也是關於driver的。
2.也是由於問題是driver爆出來的,但是driver如果在yarn-cluster模式下,由於driver是被yarn根據一定的資源調度規則隨機分配到某個node上,所以這種情況下,有可能就需要改動每個nodemanager的配置了(只是這樣猜想,因爲我的提交是yarn-client,能夠確定driver的位置,所以能夠確切知道該改哪裏的配置)
3.有可能你會說在spark-submint提交命令裏,可以指定參數,我的確這樣嘗試了,但是沒有效果,不知道是環境問題還是配錯了。小夥伴們可以嘗試一下。

操作步驟

1.連接上提交spark-submit的服務器,輸入下面命令,可以看看默認的棧大小,我的是1M

java -XX:+PrintFlagsFinal -version | grep ThreadStackSize

2.找到spark的配置文件,每個人的環境不一樣,這裏就不貼路徑了,編輯之

 vim spark-defaults.conf

3.在最後面加上如下配置,大小可根據實際情況指定,大點無所謂,小了要報錯。

spark.driver.extraJavaOptions="-Xss30M"

4.重啓spark。
5.再次嘗試提交任務,問題應該就能解決。

後續思考

1.上面的問題,是由於引用過多造成棧空間不足而報錯。但是據周志明老師的JVM書籍上提到,如果調用層次過深,超過棧深度,也會報錯,那麼假如用spark執行一條比較複雜的SQL,比如有很多的or,and之類的條件,那麼可以猜測,在解析樹的時候,大量遞歸可能會造成棧深度溢出。這只是一種猜測,留待有緣人踩坑。解決方法,目前我只想到兩種,第一是有沒有辦法增加棧深度,第二是簡化SQL語句,減少遞歸。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章