Spark常見錯誤問題匯總


一.SparkSQL相關

  • 在執行insert 語句時報錯,堆棧信息為:FileSystem closed。常常出現在ThriftServer里面。

    • 原因:由於hadoop FileSystem.get 獲得的FileSystem會從緩存加載,如果多線程一個線程closedFileSystem會導致該BUG

    • 解決方法:hdfs存在不從緩存加載的解決方式,在hdfs-site.xml 配置 fs.hdfs.impl.disable.cache=true即可

  • 在執行Spark過程中拋出:Failed to bigdata010108:33381,caused by:java.nio.channels.unresolvedAdderssException

    • 原因:該原因是由於hosts未配置,導致不識別

    • 解決方法:修改相應的機器的host即可

  • 在執行Sparksql操作orc類型的表時拋出:java.lang.IndexOutOfBoundsException 或者 java.lang.NullPointerException

    • 原因:分區或者表下存在空的orc文件。該BUG在Spark2.3.0之后才修復

    • 解決方法:規避解決。修改ORC的默認分割策略為:hive.exec.orc.split.strategy=BI進行解決。Orc的分split有3種策略(ETL、BI、HYBIRD),默認是HYBIRD(混合模式,根據文件大小和文件個數自動選擇ETL還是BI模式),BI模式是按照文件個數來分split

  • Spark2.1.0不支持永久函數,這是由於Spark2.2.0之前不支持讀取hdfs上面的jar包。

  • Saprk-sql和ThriftServer使用時報錯:Java.net.socketTimeOutException:read time out

    • 原因:是由於hivemetastore過於繁忙或者gc導致連接超時

    • 解決方法:spark-sql解決:hive.metastore.client.socket.timeout將該參數調大。ThriftServer解決辦法:在獲得一個Connection之前加上:DriverManager.setLoginTimeout(100)

  • 操作snappy壓縮的表時拋出:java.lang.RuntimeException: native snappy library not available: this version of libhadoop was built without snappy support.

    • 原因:是由於沒有在java.library.path上加上snappy庫

    • 解決方法:修改spark-default.conf配置文件加上:spark.executor.extraLibraryPath /data/Install/hadoop/lib/native 或者spark.executor.extraJavaOptions -Djava.library.path=/data/Install/hadoop/lib/native

  • Spark-sql在執行時將一個很小的文件拆分成了20個task進行運行,導致運行速度太慢。

    • 原因:是由於HaddopRDD生成過程中partitions是會拿參數mapreduce.job.maps ,或mapred.map.tasks(20)和spark默認分區數(2)做最大值比較,所以導致默認為20

    • 解決方法:修改該參數就可以將task降下來。

  • ThriftServer登錄異常:javax.security.sasl.AuthenticationException: Error validating LDAP user

    • 原因:是由於密碼錯誤或者LDAP服務異常

    • 解決方法:解決密碼和驗證問題

  • 使用jdbc的方式連接到ThriftServer,可以執行類似與show tabls的等操作,但是不能執行select相關的操作:java.io.IOException: Failed to create local dir in /tmp/blockmgr-adb70127-0a28-4256-a205-c575acc74f9d/06.

    • 原因:用戶很久沒使用ThriftServer導致系統清理了該上級目錄或者用戶根本就對該目錄沒有寫權限

    • 解決方法:重啟ThriftServer和設置目錄權限:spark.local.dir

  • 在Spark SQL中運行的SQL語句過於復雜的話,會出現 java.lang.StackOverflowError 異常

    • 原因:這是因為程序運行的時候 Stack 大小大於 JVM 的設置大小

    • 解決方法:通過在啟動 Spark-sql 的時候加上 --driver-java-options “-Xss10m” 選項解決這個問題

  • INSERT INTO重復執行出現:Unable to move source hdfs://bigdata05/tmp/hive-hduser1101_hive_2017-09-11_14-50-56_038_2358196375683362770-82/-ext-10000/part-00000 to destination hdfs://bigdata05/user/hive

    • 原因:該問題是2.1.0的Bug,在Spark2.1.1中已經解決2.1.0。

    • 解決方法:2.1.0規避辦法INSERT OVERWRITE不帶分區重復執行不會出現問題

  • 執行大數據量的join等操作時出現:1.Missing an output location for shuffle;2.Failed to connect to bigdata030015/100.103.131.13:38742; 3.FileNotFoundException……(not such file or directory)。4.Container killed on request. Exit code is 143

 

    • 原因:shuffle分為shuffle write和shuffle read兩部分。shuffle write的分區數由上一階段的RDD分區數控制,shuffle read的分區數則是由Spark提供的一些參數控制。shuffle write可以簡單理解為類似於saveAsLocalDiskFile的操作,將計算的中間結果按某種規則臨時放到各個executor所在的本地磁盤上。

      • shuffle read的時候數據的分區數則是由spark提供的一些參數控制。可以想到的是,如果這個參數值設置的很小,同時shuffle read的量很大,那么將會導致一個task需要處理的數據非常大。結果導致JVM crash(OOM),從而導致取shuffle數據失敗,同時executor也丟失了,看到Failed to connect to host的錯誤,也就是executor lost的意思。有時候即使不會導致JVM crash也會造成長時間的gc

    • 解決方法:1. 調優sql。

      • 2.SparkSQL和DataFrame的join,group by等操作通過spark.sql.shuffle.partitions控制分區數,默認為200,根據shuffle的量以及計算的復雜度提高這個值。

      • 3.Rdd的join,groupBy,reduceByKey等操作,通過spark.default.parallelism控制shuffle read與reduce處理的分區數,設置大一點。

      • 4.通過提高executor的內存設置spark.executor.memory適當提高executor的memory值。

      • 5.判斷join過程中是否存在數據傾斜的問題:可以參考鏈接:https://tech.meituan.com/spark-tuning-pro.html

  • Sparksql使用過程中Executor端拋出:java.lang.OutOfMemoryError: GC overhead limit exceeded

 

    • 原因:這是由於大部分事件都在GC,導致OOM。

    • 解決方法:加大執行器內存,修改GC策略spark.executor.extraJavaOptions -XX:+UseG1GC

 

  • hiveserver2和SparkThriftServer使用操作orc表的時候報錯A用戶無法訪問B用戶的目錄。

    • 原因:這是由於orc 在進行Split過沖中會進行用戶緩存。ORC在hive1.2.1時的BUG,在hive2.X和Spark2.3.X版本后進行了解決

    • 解決方法:暫時規避方法比較暴力,1、先使用超級用戶進行第一次查詢,導致緩存的用戶為超級用戶。2、設置hive.fetch.task.conversion=none不進行緩存

  • spark-sql在使用過程中小數據量查詢很慢,查看sparkUI顯示每個Task處理都很快,但是都隔了3秒進行調度導致整體很慢。

    • 原因:這是由於數據本地性導致的,默認spark.locality.wait為3秒

    • 解決方法:設置該參數為0即可加快速度,只有在數據量較小的情況下才建議這樣設置。

       

二.Spark core相關

  • on yarn啟動spark-sql 和spark-submit時出現:java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig

    • 原因:和yarn相關Jersey包沖突

    • 解決方法:配置上–conf spark.hadoop.yarn.timeline-service.enabled=false

  • 在使用Spark過程中出現:java.io.IOException: No space left on device

    • 原因:一般是由於Spark的tmp目錄滿了導致

    • 解決方法:可以將該目錄空間設置大點,支持按逗號分割多個目錄:spark.local.dir

  • 超出最大結果集:is bigger than spark.driver.maxResultSize (2.0GB)

    • 原因:spark.driver.maxResultSize默認配置為1G

    • 解決方法:調大該參數即可

  • 常見OOM:java.lang.OutOfMemoryError: Java heap space

    • 原因:1、數據量太大,申請的Executor資源不足以支撐。2.單分區的數據量過大,和分區數過多導致執行task和job存儲的信息過多導致Driver OutOfMemoryError

    • 解決方法:1、盡量不要使用collect操作。2、查看數據是否有傾斜,增加shuffle的並行度,加大Executor內存

  • 由Executor的FullGC引起Executor lost,task失敗,各種超時:Futures timed out after【120S】

    • 原因:一般是由於Executor處理數據量過大如傾斜導致,從而使Executor full gc導致時間超時,Executor 和 task 的lost

    • 解決方法:1、如果通過查看Executor的日志是full GC導致,適當調優SQL,加大Executor內存。2、如果沒有fullGC考慮提高:spark.network.timeout

  • jar包版本沖突時:java.lang.ClassNotFoundException: XXX

    • 原因:一般可能是用戶jar和Spark jar沖突

    • 解決方法:1、最好和Spark相關的jar進行適配。2、如果不行可以使用參數:spark.driver.userClassPathFirst和spark.executor.userClassPathFirst 設置為true

       

  • 進行shuffle拋出:Shuffle Fetch Failed: OOM

    • 原因:Shuffle fetch階段開啟的fetch數據量過大導致

    • 解決方法:1、加大Executor內存。2、將參數spark.reduce.maxSizeInFlight調小,默認48M

  • shuffle報org.apache.spark.shuffle.FetchFailedException: Direct buffer memory

    • 原因:堆外內存不夠導致,直接內存

    • 解決方法:增大JVM 參數-XX:MaxDirectMemorySize(如:spark.executor.extraJavaOptions = -XX:MaxDirectMemorySize=xxxm)

  • 集群節點異常導致Spark job失敗,如磁盤只讀。

      • 原因:Spark 是一個高性能、容錯的分布式計算框架,一旦它知道某個計算所在的機器出現問題會依據之前生成的 lineage 重新在這台機器上調度這個 Task,如果超過失敗次數就會導致job失敗。

      • 解決方法:Spark有黑名單機制,在超出一定次數的失敗后不會往該節點或者Executor調度Task。設置相應Black參數:spark.blacklist.enabled=true

三.Streaming相關

  • 消費kafka時,第一個job讀取了現有所有的消息,導致第一個Job處理過久甚至失敗

    • 原因:auto.offset.reset設置為了earliest 從最早的offset開始進行消費,也沒有設置spark.streaming.kafka.maxRatePerPartition參數

    • 解決方法:指定從之前開始消費的數據開始:設置offsetRange。並將參數設置為:auto.offset.reset=latest 設置Spark每個分區的速率。

  • 盡量使用高性能算子

    • 使用reduceByKey/aggregateByKey替代groupByKey

    • 使用mapPartitions替代普通map

    • 使用foreachPartitions替代foreach

    • 使用filter之后進行coalesce操作

    • 使用repartitionAndSortWithinPartitions替代repartition與sort類操作

  • Streaming如果存在多個Batch延遲時,消費不過來。有時會報出:Hbase相關的異常如:RegionTooBusyException

    • 原因:Streaming在進行處理時如果單個Batch讀取的數據多,會導致計算延遲甚至導致存儲組件性能壓力

    • 解決方法:1、如果是計算延遲試着調整讀取速率如:spark.streaming.kafka.maxRatePerPartition參數 2、調優存儲組件的性能 3、開啟Spark的反壓機制:spark.streaming.backpressure.enabled,該參數會自動調優讀取速率。但是如果設置了spark.streaming.receiver.maxRate 或 spark.streaming.kafka.maxRatePerPartition,那么最后到底接收多少數據取決於三者的最小值

  • 消費kafka時,讀取消息報錯:OffsetOutOfRangeException

    • 原因:讀取的offsetRange超出了Kafka的消息范圍,如果是小於也就是kafka保存的消息已經被處理掉了(log.retention.hours)。或者超出Kafka現有的offset

    • 解決方法:在讀取offset時先進行校正,拿到offset的earliestOffset 和lastestOffset

  • Kafka抖動導致No leader found

      • kafka變更或者其他原因導致

      • 解決方法:設置 spark.streaming.kafka.maxRetries 大於1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM