本文匯總了使用DLA Spark的常見問題及解決方案。
常見問題
如何處理Spark作業報錯:The VirtualCluster's name is invalid or the VirtualCluster's is not in running state?
如何處理Spark作業報錯:User %s do not have right permission [ *** ] to resource [ *** ]?
如何處理Spark SQL讀JSON外表(包含日誌投遞自建)時的報錯ClassNotFoundException: org.apache.hadoop.hive.serde2.JsonSerDe?
如何處理執行Spark SQL報錯:Exception in thread "main" java.io.IOException: No FileSystem for scheme: oss?
常見問題
如何處理Spark作業報錯:The VirtualCluster's name is invalid or the VirtualCluster's is not in running state?
常見原因:虛擬叢集名稱(VcName)沒配置,一般是由於該虛擬叢集不存在或者該虛擬叢集不是在運行中狀態
解決方案:您需要填寫正確的虛擬叢集,如下所示。
如果該錯誤是DLA控制台作業管理介面報出,請先建立虛擬叢集,再提交作業。
如果您使用的不是控制台方式,而是Aliyun OpenAPI、Spark-submit指令碼或者Jupyter等,需要檢查配置參數VcName對應的需求叢集是否未填寫或者填寫錯誤。尋找可用的虛擬叢集名稱的方法如下。
登入DLA控制台。
左側導覽列單擊虛擬叢集管理。
在虛擬叢集列表中選擇狀態是運行中的虛擬叢集的名字。
如何處理Spark作業報錯:User %s do not have right permission [ *** ] to resource [ *** ]?
常見原因:當前子帳號沒有調用該介面的許可權。
解決方案如下。
配置相應許可權,詳情請參見快速配置子帳號許可權。
登入RAM控制台為該帳號添加報錯資訊中對應的Resource許可權。
如何處理Spark作業報錯:No space left on device?
首先判斷報錯資訊是否是Executor本地記憶體不足導致的,判斷方法是查看SparkUI中Executor的Stderr日誌資訊。如果是,您可以通過添加如下配置來增加Executor本地碟的大小。
spark.k8s.shuffleVolume.enable: true
spark.dla.local.disk.size: 50Gi
本地碟為ESSD類型,暫時免費,後續會收費。
當前本地碟最大為100Gi。
如果已經配置了100Gi的本地碟,仍然提示空間不足,那麼可以考慮增加Executor的數量。
Spark Executor出現Dead怎麼處理?
首先進入SparkUI頁面,如果Failed Stages的Failure reason中包含Failed to connect to /xx.xx.xx.xx:xxxx或者在SparkUI->Executors頁面出現狀態為Dead的Executor,往往是因為Spark Executor由於某種原因退出了。
如何進入SparkUI頁面,詳情請參見Spark UI。
常見情境如下。
Driver日誌出現如下報錯:ERROR TaskSchedulerImpl: Lost executor xx on xx.xx.xx.xx:The executor with id xx exited with exit code 137.
原因:Executor進程記憶體用超了。容器的整體記憶體使用量超過了容器最大允許使用記憶體上限,導致Spark進程被kill-9強制殺掉了。Spark Executor除了JVM本身使用記憶體外,往往還包括堆外記憶體(Shuffle、Cache),以及Python UDF等使用的記憶體。
解決方案:調大參數spark.executor.memoryOverhead(單位MB)。該參數表示容器內部非Spark Executor進程可使用的記憶體容量,預設是Executor容器總記憶體容量的30%。比如您當前配置的Executor規格是Medium(2C8G),那麼預設的MemoryOverhead是2.4G,您可以調大該配置如下:
spark.executor.memoryOverhead = 4000。
2.日誌中出現java.lang.OutOfMemoryError的日誌。
原因:在SparkUI->Executors頁面查看狀態為Dead的Executor的stderr/stdout日誌連結尋找具體報錯原因。
解決方案如下。
最佳化應用,避免大記憶體佔用。
調大Executor資源規格,比如Small提高到Medium。
3.除上述報錯以外,其他報錯的解決方案。
查看Dead狀態的Executor日誌,如果報錯位置位於使用者業務代碼,需要業務開發解決。其他錯誤資訊您可以在搜尋引擎中搜尋相關報錯資訊。
Spark訪問資料來源網路不通怎麼辦?
預設情況下,DLA Spark不能訪問使用者VPC,只能訪問OSS、Tablestore、MaxCompute等服務型資料來源,並且不能訪問公網。
DLA Spark可以通過掛載使用者VPC網卡的方式來訪問使用者VPC中的資料來源,以及訪問公網。掛載使用者網卡後,網路模型與一台普通使用者VPC的ECS完全一樣,可以複用阿里雲VPC網路產品的所有功能,包括內網、公網、專線等等。如何掛載使用者網卡,詳情請參見文檔配置資料來源網路。
如何處理Spark作業日誌中報錯:ClassNotFound?
常見原因:一般是由於缺少類導致。您可以通過開啟所上傳的JAR包(jar tvf xxx.jar | grep xxxx),確認該類是否存在。
解決方案如下。
如果是使用者業務相關的類,需要重新打包,確保目標類被打進去。
如果是第三方包,您可以採用如下方式。
使用Maven的Shade或者Assembly外掛程式,加入依賴包(Shade和Assembly可以自行尋找Maven相關資料)。
使用作業配置指南中“jars”參數將第三方JAR包單獨上傳。
如何處理Spark作業日誌中報錯:NoSuchMethod?
常見原因:出現了JAR包衝突,可能是引入了跟Spark衝突的第三方包導致。
解決方案:您可以通過Provided、Relocation等Maven常見的衝突解決方式來解決,相關技術屬於通用技術,您可以進行搜尋或者參考dla spark demo專案進行Maven Pom配置。
為什麼Spark SQL作業使用show tables或者show database查詢發現顯示的列表不足?
首先請確認是否使用了DLA的中繼資料服務。
如果您使用的是DLA的中繼資料服務,需要確認許可權問題。您只能看到自己具有許可權的庫表,其他庫表隱藏。
如果您使用的不是DLA的中繼資料服務,需要確認自建中繼資料服務的許可權和連通的正確性。
為什麼在DLA SQL中執行select * from db1.table1成功, 但在Spark中報錯?
詳細報錯如下。
java.lang.NullPointerException
at java.net.URI$Parser.parse(URI.java:3042)
at java.net.URI.<init>(URI.java:588)
at org.apache.spark.sql.hive.client.JianghuClientImpl$$anonfun$getTableOption
常見原因如下。
表的儲存格式不對,目前只支援OSS和HDFS。
表名中出現了中劃線
-
,中劃線為Spark SQL保留字,不允許在表名中使用。
為什麼在DLA SQL中執行select * from db1.table1有資料,但在Spark中沒有?
常見原因如下。
表中對應的OSS或者HDFS地址有嵌套關係。例如您指定的LOCATION為
oss://db/table/
, 指定了partiion1和parition2,則您的資料檔案應當類似oss//db/table/partition1=a/partiion2=b/data.csv
。DLA SQL支援多層嵌套目錄oss//db/table/partition1=a/partiion2=b/extral_folder/data.csv
,但Spark SQL暫不支援。DLA SQL的文法和Spark SQL的文法略有區別,如何調試SQL,請參見Spark SQL。
為什麼Spark作業提示錯誤記錄檔oss object 403?
常見原因如下。
DLA Spark不支援跨Region讀JAR包或者讀檔案。
通過參數spark.dla.rolearn指定的Role沒有讀取這個OSS路徑的許可權。
檔案地址填寫錯誤。
檔案與檔案之間沒有用逗號隔開或者寫成JSON的List。
如何處理Spark SQL讀JSON外表(包含日誌投遞自建)時的報錯ClassNotFoundException: org.apache.hadoop.hive.serde2.JsonSerDe?
解決方案具體步驟如下。
下載https://repo1.maven.org/maven2/org/apache/hive/hive-serde/3.1.2/hive-serde-3.1.2.jar上傳至OSS。
在Spark SQL開頭添加語句
add jar oss://path/to/hive-serde-3.1.2.jar;
。
如何處理執行Spark SQL報錯:Exception in thread "main" java.io.IOException: No FileSystem for scheme: oss?
解決方案:您可以在Spark SQL中添加如下命令。
set spark.dla.connectors=oss;
作業慢如何排查?
常見的作業執行慢可以分為兩大類:
作業異常導致,您可以通過下面方法1和方法2排查。
作業無異常仍然很慢,您可以通過方法3、方法4和方法5排查。
1. 查看是否有Executor狀態是Dead。
查看方式:單擊展開對應作業的操作列表,點擊SparkUI進入Spark頁面,切換到Executors頁面,查看Status欄位。
解決方案:具體解決辦法請參見Spark Executor出現Dead怎麼處理。
2. 查看Driver日誌,是否有異常資訊導致Task終止並重試。
查看方式:單擊展開對應作業的操作列表,點擊SparkUI進入Spark頁面,切換到Executors頁面,找到Executor ID欄位中為driver的stderr日誌。
解決方案:通過報錯資訊查看異常的具體原因,大部分跟商務邏輯相關,您可以對其進行排查或者通過搜尋引擎搜尋解決。
如果是OOM異常則需要檢查商務邏輯是否有大記憶體佔用,特別是某個欄位特別大的情況,如果確實需要更大記憶體,您可以考慮使用更大規格的Executor或Driver節點。
3. 查看是否由資源不足導致。
查看方法:單擊展開對應作業的操作列表,點擊SparkUI進入Spark頁面,切換到Stages頁面,從Stage列表中,找到執行比較慢的一些Stage,查看這些Stage的並發度(Tasks: Succeeded/Total)。
如果Stage的Total比(Executor數目)*(Executor cores)多,那麼就確認存在資源不足。
比如某個Stage Tasks Total是100,spark.executor.instances=5,spark.executor.resourceSpec=medium(2C8G),那麼每一輪Tasks只能跑10個,需要跑10輪。
此時需要增加作業的資源總量,調大spark.executor.instances參數,或者調大Executor規格(spark.executor.resourceSpec)。最好不要超過同時啟動並執行Stage的Tasks總數,否則會導致資源浪費。
4. 查看是否由GC導致。
查看方式:單擊展開對應作業的操作列表,點擊SparkUI進入Spark頁面,切換到Executors頁面,查看Task Time (GC Time)欄位。
如果某些Executor GC Time比較多時,您可以採取如下解決方案。
最佳化邏輯。
增大Executor或Driver的節點規格。
5. 查看Driver或Executor堆棧慢在哪裡。
查看方式:單擊展開對應作業的操作列表,點擊SparkUI進入Spark頁面,切換到Executors頁面,查看Thread Dump欄位。
堆棧只有在作業running狀態才能查看。
解決方案:多次重新整理堆棧查看作業運行卡在什麼地方。
如果集中卡在某一個或者某幾個函數調用上,那麼說明該部分邏輯有熱點或者實現效率比較低,您可以考慮最佳化該部分邏輯。
如果卡在Spark的某些調用中,您可以通過搜尋引擎搜尋解決。