1. 程式人生 > >spark常見問題錯誤 彙總

spark常見問題錯誤 彙總

一.經驗

1.Spark Streaming包含三種計算模式:nonstate .stateful .window

2.kafka可通過配置檔案使用自帶的zookeeper叢集

3.Spark一切操作歸根結底是對RDD的操作

4.部署Spark任務,不用拷貝整個架包,只需拷貝被修改的檔案,然後在目標伺服器上編譯打包。

5.kafka的log.dirs不要設定成/tmp下的目錄,貌似tmp目錄有檔案數和磁碟容量限制

6.ES的分片類似kafka的partition

7spark Graph根據邊集合構建圖,頂點集合只是指定圖中哪些頂點有效

8.presto叢集沒必要採用on yarn模式,因為hadoop依賴HDFS,如果部分機器磁碟很小,hadoop會很尷尬,而presto是純記憶體計算,不依賴磁碟,獨立安裝可以跨越多個叢集,可以說有記憶體的地方就可以有presto

9.presto程序一旦啟動,JVM server會一直佔用記憶體

10.如果maven下載很慢,很可能是被天朝的GFW牆了,可以在maven安裝目錄的setting.conf配置檔案mirrors標籤下加入國內映象抵制**黨的網路封鎖,例如:

<mirror>
  <id>nexus-aliyun</id>
  <mirrorOf>*</mirrorOf>
  <name>Nexus aliyun</name>
  <url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>

11.編譯spark,hive on spark就不要加-Phive引數,若需sparkSQL支援hive語法則要加-Phive引數

12.通過hive原始檔pom.xml檢視適配的spark版本,只要打版本保持一致就行,例如spark1.6.0和1.6.2都能匹配

13.開啟Hive命令列客戶端,觀察輸出日誌是否有列印“SLF4J: Found binding in [jar:file:/work/poa/hive-2.1.0-bin/lib/spark-assembly-1.6.2-hadoop2.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]”來判斷hive有沒有繫結spark

14.kafka的comsumer groupID對於spark direct streaming無效

15.shuffle write就是在一個stage結束計算之後,為了下一個stage可以執行shuffle類的運算元,而將每個task處理的資料按key進行分類,將相同key都寫入同一個磁碟檔案中,而每一個磁碟檔案都只屬於下游stage的一個task,在將資料寫入磁碟之前,會先將資料寫入記憶體快取中,下一個stage的task有多少個,當前stage的每個task就要建立多少份磁碟檔案。

16.單個spark任務的excutor核數不宜設定過高,否則會導致其他JOB延遲

17.資料傾斜只發生在shuffle過程,可能觸發shuffle操作的運算元有:distinctgroupByKeyreduceByKeyaggregateByKeyjoincogrouprepartition

18.執行時刪除hadoop資料目錄會導致依賴HDFS的JOB失效

19.sparkSQL UDAF中update函式的第二個引數 input: Row 對應的並非DataFrame的行,而是被inputSchema投影了的行

20.Spark的Driver只有在Action時才會收到結果

21.Spark需要全域性聚合變數時應當使用累加器(Accumulator)

22.Kafka以topic與consumer group劃分關係,一個topic的訊息會被訂閱它的消費者組全部消費,如果希望某個consumer使用topic的全部訊息,可將該組只設一個消費者,每個組的消費者數目不能大於topic的partition總數,否則多出的consumer將無消可費

23.所有自定義類要實現serializable介面,否則在叢集中無法生效

24.resources資原始檔讀取要在Spark Driver端進行,以區域性變數方式傳給閉包函式

25.DStream流轉化只產生臨時流物件,如果要繼續使用,需要一個引用指向該臨時流物件

26.提交到yarn cluster的作業不能直接print到控制檯,要用log4j輸出到日誌檔案中

27.HDFS檔案路徑寫法為:hdfs://master:9000/檔案路徑,這裡的master是namenode的hostname,9000是hdfs埠號。

28.不要隨意格式化HDFS,這會帶來資料版本不一致等諸多問題,格式化前要清空資料資料夾

29.搭建叢集時要首先配置好主機名,並重啟機器讓配置的主機名生效

30.linux批量多機互信, 將pub祕鑰配成一個

31小於128M的小檔案都會佔據一個128M的BLOCK,合併或者刪除小檔案節省磁碟空間

32.Non DFS Used指的是非HDFS的所有檔案

33.spark兩個分割槽方法coalesce和repartition,前者窄依賴,分割槽後資料不均勻,後者寬依賴,引發shuffle操作,分割槽後資料均勻

34.spark中資料寫入ElasticSearch的操作必須在action中以RDD為單位執行

35.可以通過hive-site.xml修改spark.executor.instancesspark.executor.coresspark.executor.memory等配置來優化hive on spark執行效能,不過最好配成動態資源分配。

二.基本功能

0.常見問題:

1如果執行程式出現錯誤:Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory,這是因為專案缺少slf4j-api.jarslf4j-log4j12.jar這兩個jar包導致的錯誤。
2如果執行程式出現錯誤:java.lang.NoClassDefFoundError: org/apache/log4j/LogManager,這是因為專案缺少log4j.jar這個jar包
3錯誤:Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.MDC.getCopyOfContextMap()Ljava/util/Map,這是因為jar包版本衝突造成的。

1.配置spark-submit (CDH版本)

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream
        at org.apache.spark.deploy.SparkSubmitArguments.handleUnknown(SparkSubmitArguments.scala:451)
        at org.apache.spark.launcher.SparkSubmitOptionParser.parse(SparkSubmitOptionParser.java:178)
        at org.apache.spark.deploy.SparkSubmitArguments.<init>(SparkSubmitArguments.scala:97)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:113)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.fs.FSDataInputStream
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 5 more

解決方案:

spark-env.sh檔案中新增:

export SPARK_DIST_CLASSPATH=$(hadoop classpath)

2.啟動spark-shell時,報錯

INFO cluster.YarnClientSchedulerBackend: Registered executor: Actor[akka.tcp://[email protected]:34965/user/Executor#1736210263] with ID 1
INFO util.RackResolver: Resolved services07 to /default-rack
INFO storage.BlockManagerMasterActor: Registering block manager services07:51154 with 534.5 MB RAM

解決方案:

在spark的spark-env配置檔案中配置下列配置項:

將export SPARK_WORKER_MEMORY, export SPARK_DRIVER_MEMORY, export SPARK_YARN_AM_MEMORY的值設定成小於534.5 MB

3.啟動spark SQL時,報錯:

  Caused by: org.datanucleus.store.rdbms.connectionpool.DatastoreDriverNotFoundException: The specified datastore driver ("com.mysql.jdbc.Driver ") was not found in the CLASSPATH. Please check your CLASSPATH specification, and the name of the driver.

解決方案:

$SPARK_HOME/conf/spark-env.sh檔案中配置:

export SPARK_CLASSPATH=$HIVE_HOME/lib/mysql-connector-java-5.1.6-bin.jar

4.啟動spark SQL時,報錯:

  java.sql.SQLException: Access denied for user 'services02 '@'services02' (using password: YES)

解決方案:

檢查hive-site.xml的配置項, 有以下這個配置項

<property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>123456</value>
    <description>password to use against metastore database</description>
</property>

看該密碼與與MySQL的登入密碼是否一致

5.啟動計算任務時報錯:

報錯資訊為:

  org.apache.spark.rpc.RpcTimeoutException: Futures timed out after [120 seconds]. This timeout is controlled by spark.rpc.askTimeout

解決方案:

  分配的core不夠, 多分配幾核的CPU

6.啟動計算任務時報錯:

不斷重複出現

  status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1     
  status.SparkJobMonitor: 2017-01-04 11:53:54,564    Stage-0_0: 0(+1)/1     
  status.SparkJobMonitor: 2017-01-04 11:53:55,564    Stage-0_0: 0(+1)/1     
  status.SparkJobMonitor: 2017-01-04 11:53:56,564    Stage-0_0: 0(+1)/1             

解決方案:

    資源不夠, 分配大點記憶體, 預設值為512MB.

7.啟動Spark作為計算引擎時報錯:

報錯資訊為:

java.io.IOException: Failed on local exception: java.nio.channels.ClosedByInterruptException; Host Details : local host is: "m1/192.168.179.201"; destination host is: "m1":9000; 
    at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:772)
    at org.apache.hadoop.ipc.Client.call(Client.java:1474)
Caused by: java.nio.channels.ClosedByInterruptException
    at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:202)
    at sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:681)
17/01/06 11:01:43 INFO retry.RetryInvocationHandler: Exception while invoking getFileInfo of class ClientNamenodeProtocolTranslatorPB over m2/192.168.179.202:9000 after 9 fail over attempts. Trying to fail over immediately.

解決方案:

出現該問題的原因有多種, 我所遇到的是使用Hive On Spark時報了此錯誤,解決方案是:
hive-site.xml檔案下正確配置該項

<property>
    <name>spark.yarn.jar</name>
    <value>hdfs://ns1/Jar/spark-assembly-1.6.0-hadoop2.6.0.jar</value>
</property>

8.啟動spark叢集時報錯,啟動命令為:start-mastersh

報錯資訊:

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/Logger
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
        at java.lang.Class.getMethod0(Class.java:3018)
        at java.lang.Class.getMethod(Class.java:1784)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.slf4j.Logger
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 7 more

解決方案:

/home/centos/soft/hadoop/share/hadoop/common/lib目錄下的slf4j-api-1.7.5.jar檔案,slf4j-log4j12-1.7.5.jar檔案和commons-logging-1.1.3.jar檔案拷貝到/home/centos/soft/spark/lib目錄下

9.啟動spark叢集時報錯,啟動命令為:start-mastersh

報錯資訊:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/conf/Configuration
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2570)
        at java.lang.Class.getMethod0(Class.java:2813)
        at java.lang.Class.getMethod(Class.java:1663)
        at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.conf.Configuration
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        ... 6 more

解決方案:

官網資料:
    https://spark.apache.org/docs/latest/hadoop-provided.html#apache-hadoop

編輯/home/centos/soft/spark/conf/spark-env.sh檔案,配置下列配置項:

export SPARK_DIST_CLASSPATH=$(/home/centos/soft/hadoop/bin/hadoop classpath)

10.啟動HPL/SQL儲存過程時報錯:

報錯資訊:

2017-01-10T15:20:18,491 ERROR [HiveServer2-Background-Pool: Thread-97] exec.TaskRunner: Error in executeTask
java.lang.OutOfMemoryError: PermGen space
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
2017-01-10T15:20:18,491 ERROR [HiveServer2-Background-Pool: Thread-97] ql.Driver: FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.spark.SparkTask. PermGen space
2017-01-10T15:20:18,491  INFO [HiveServer2-Background-Pool: Thread-97] ql.Driver: Completed executing command(queryId=centos_20170110152016_240c1b5e-3153-4179-80af-9688fa7674dd); Time taken: 2.113 seconds
2017-01-10T15:20:18,500 ERROR [HiveServer2-Background-Pool: Thread-97] operation.Operation: Error running hive query: 
org.apache.hive.service.cli.HiveSQLException: Error while processing statement: FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.spark.SparkTask. PermGen space
        at org.apache.hive.service.cli.operation.Operation.toSQLException(Operation.java:388)
        at org.apache.hive.service.cli.operation.SQLOperation.runQuery(SQLOperation.java:244)
        at org.apache.hive.service.cli.operation.SQLOperation.access$800(SQLOperation.java:91)
Caused by: java.lang.OutOfMemoryError: PermGen space
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)

解決方案:

參考資料:
    http://blog.csdn.net/xiao_jun_0820/article/details/45038205

出現該問題是因為Spark預設使用全部資源, 而此時主機的記憶體已用, 應在Spark配置檔案中限制記憶體的大小.
hive-site.xml檔案下配置該項:

<property>
    <name>spark.driver.extraJavaOptions</name>
    <value>-XX:PermSize=128M -XX:MaxPermSize=512M</value>
</property>

或在spark-default.conf檔案下配置:

spark.driver.extraJavaOptions             -XX:PermSize=128M -XX:MaxPermSize=256M

三.Spark常見問題彙總

1.報錯資訊:

Operation category READ is not supported in state standbyorg.apache.hadoop.ipc.RemoteException(org.apache.hadoop.ipc.StandbyException): 
Operation category READ is not supported in state standby

解決方案:

檢視執行Spark計算的是否處於standby狀態, 用瀏覽器訪問該主機:http://m1:50070, 如果處於standby狀態, 則不可在處於StandBy機器執行spark計算,應切執行Spark計算的主機從Standby狀態切換到Active狀態

2.問題出現情景:

Spakr叢集的所有執行資料在Master重啟是都會丟失

解決方案:

配置spark.deploy.recoveryMode選項為ZOOKEEPER

3.報錯資訊:

由於Spark在計算的時候會將中間結果儲存到/tmp目錄,而目前linux又都支援tmpfs,其實就是將/tmp目錄掛載到記憶體當中, 那麼這裡就存在一個問題,中間結果過多導致/tmp目錄寫滿而出現如下錯誤

No Space Left on the device(Shuffle臨時檔案過多)

解決辦法:

修改配置檔案spark-env.sh,把臨時檔案引入到一個自定義的目錄中去, 即:

export SPARK_LOCAL_DIRS=/home/utoken/datadir/spark/tmp

4.報錯資訊:

java.lang.OutOfMemory, unable to create new native thread
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:640)

解決方案:

上面這段錯誤提示的本質是Linux作業系統無法建立更多程序,導致出錯,並不是系統的記憶體不足。因此要解決這個問題需要修改Linux允許建立更多的程序,就需要修改Linux最大程序數。
(1)修改Linux最大程序數

ulimit -a

(2)臨時修改允許開啟的最大程序數

ulimit -u 65535

(3)臨時修改允許開啟的檔案控制代碼

ulimit -n 65535

(4)永久修改Linux最大程序數量

sudo vi /etc/security/limits.d/90-nproc.conf
*          soft    nproc     60000
root       soft    nproc     unlimited

永久修改使用者開啟檔案的最大控制代碼數,該值預設1024,一般都會不夠,常見錯誤就是not open file
解決辦法:

sudo vi /etc/security/limits.conf
bdata  soft    nofile  65536
bdata  hard    nofile  65536

5.問題出現情景:

Worker節點中的work目錄佔用許多磁碟空間, 這些是Driver上傳到worker的檔案, 會佔用許多磁碟空間.

解決方案:

需要定時做手工清理. 目錄地址:/home/centos/soft/spark/work

6.問題出現情景:

spark-shell提交Spark Application如何解決依賴庫

解決方案:

利用--driver-class-path選項來指定所依賴的jar檔案,注意的是--driver-class-path後如果需要跟著多個jar檔案的話,jar檔案之間使用冒號:來分割。

7.Spark在釋出應用的時候,出現連線不上master

報錯資訊如下:

INFO AppClient$ClientEndpoint: Connecting to master spark://s1:7077...
WARN ReliableDeliverySupervisor: Association with remote system [akka.tcp://[email protected]:7077] has failed, address is now gated for [5000] ms. Reason: [Disassociated]

解決方案:

檢查所有機器時間是否一致.hosts是否都配置了對映.客戶端和伺服器端的Scala版本是否一致.Scala版本是否和Spark相容

8.開發spark應用程式(和Flume-NG結合時)釋出應用時可能會報錯

報錯資訊如下:

ERROR ReceiverSupervisorImpl: Stopped receiver with error: org.jboss.netty.channel.ChannelException: Failed to bind to: /192.168.10.156:18800
ERROR Executor: Exception in task 0.0 in stage 2.0 (TID 70)
                org.jboss.netty.channel.ChannelException: Failed to bind to: /192.168.10.156:18800
                at org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:272)
Caused by: java.net.BindException: Cannot assign requested address

解決方案:

參考資料:
  http://www.tuicool.com/articles/Yfi2eyR

由於spark通過Master釋出的時候,會自動選取傳送到某一臺的worker節點上,所以這裡繫結埠的時候,需要選擇相應的worker伺服器,但是由於我們無法事先了解到,spark釋出到哪一臺伺服器的,所以這裡啟動報錯,是因為在192.168.10.156:18800的機器上面沒有啟動Driver程式,而是釋出到了其他伺服器去啟動了,所以無法監聽到該機器出現問題,所以我們需要設定spark分發包時,釋出到所有worker節點機器,或者釋出後,我們去尋找釋出到了哪一臺機器,重新修改繫結IP,重新發布,有一定機率釋出成功。

9.使用Hive on Spark時報錯:

ERROR XSDB6: Another instance of Derby may have already booted the database /home/bdata/data/metastore_db.

解決方案:

在使用Hive on Spark模式操作hive裡面的資料時,報以上錯誤,原因是因為HIVE採用了derby這個內嵌資料庫作為資料庫,它不支援多使用者同時訪問,解決辦法就是把derby資料庫換成mysql資料庫即可

10.找不到hdfs叢集名字dfscluster

報錯資訊:

  java.lang.IllegalArgumentException: java.net.UnknownHostException: dfscluster

解決辦法:

$HADOOP_HOME/etc/hadoop/hdfs-site.xml檔案拷貝到Spark叢集的所有主機的$SPARK_HOME/conf目錄下,然後重啟Spark叢集

cd /home/centos/soft/spark/conf/
for i in {201,202,203}; 
do scp hdfs-site.xml 192.168.179.$i:/home/centos/soft/spark/conf/; 
done

11.在執行yarn叢集或者客戶端時,報錯:

執行指令:

sh $SPARK_HOME/bin/spark-sql --master yarn-client

報如下錯誤:

Exception in thread "main" java.lang.Exception: When running with master 'yarn-client' either HADOOP_CONF_DIR or YARN_CONF_DIR must be set in the environment.

解決辦法:

根據提示,配置HADOOP_CONF_DIR or YARN_CONF_DIR的環境變數即可, 在spark-env.sh檔案中配置以下幾項:

export HADOOP_HOME=/u01/hadoop-2.6.1
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
PATH=$PATH:$HIVE_HOME/bin:$HADOOP_HOME/bin

12.提交spark計算任務時,報錯:

報錯資訊如下:

Job aborted due to stage failure: Task 3 in stage 0.0 failed 4 times, most recent failure: Lost task 3.3 in
[org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 0 on 192.168.10.38: remote Rpc client disassociated
[org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 1 on 192.168.10.38: remote Rpc client disassociated
[org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 2 on 192.168.10.38: remote Rpc client disassociated
[org.apache.spark.scheduler.TaskSchedulerImpl]-[ERROR] Lost executor 3 on 192.168.10.38: remote Rpc client disassociated
[org.apache.spark.scheduler.TaskSetManager]-[ERROR] Task 3 in stage 0.0 failed 4 times; aborting job
Exception in thread "main" org.apache.spark.SparkException : Job aborted due to stage failure: Task 3 in stage 0.0 failed 4 times, most recent failure: Lost task 3.3 in stage 0.0 (TID 14, 192.168.10.38): ExecutorLostFailure (executor 3 lost)
Driver stacktrace:
at org.apache.spark.scheduler.DAGScheduler.org$apache$spark$scheduler$DAGScheduler$$failJobAndIndependentStages(DAGScheduler.scala:1283)

解決方案:

這裡遇到的問題主要是因為資料來源資料量過大,而機器的記憶體無法滿足需求,導致長時間執行超時斷開的情況,資料無法有效進行互動計算,因此有必要增加記憶體

13.啟動Spark計算任務:

長時間等待無反應,並且看到伺服器上面的web介面有記憶體和核心數,但是沒有分配,報錯資訊如下:

status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1
status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1
status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1
status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1
status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1
status.SparkJobMonitor: 2017-01-04 11:53:51,564    Stage-0_0: 0(+1)/1

日誌資訊顯示:

WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient resources

解決方案:

出現上面的問題主要原因是因為我們通過引數spark.executor.memory設定的記憶體過大,已經超過了實際機器擁有的記憶體,故無法執行,需要等待機器擁有足夠的記憶體後,才能執行任務,可以減少任務執行記憶體,設定小一些即可

14.記憶體不足或資料傾斜導致Executor Lost(spark-submit提交)

報錯資訊如下:

TaskSetManager: Lost task 1.0 in stage 6.0 (TID 100, 192.168.10.37): java.lang.OutOfMemoryError: Java heap space
INFO BlockManagerInfo: Added broadcast_8_piece0 in memory on 192.168.10.37:57139 (size: 42.0 KB, free: 24.2 MB)
INFO BlockManagerInfo: Added broadcast_8_piece0 in memory on 192.168.10.38:53816 (size: 42.0 KB, free: 24.2 MB)
INFO TaskSetManager: Starting task 3.0 in stage 6.0 (TID 102, 192.168.10.37, ANY, 2152 bytes)
WARN TaskSetManager: Lost task 1.0 in stage 6.0 (TID 100, 192.168.10.37): java.lang.OutOfMemoryError: Java heap space
            at java.io.BufferedOutputStream.<init>(BufferedOutputStream.java:76)
            at java.io.BufferedOutputStream.<init>(BufferedOutputStream.java:59)
            at org.apache.spark.sql.execution.UnsafeRowSerializerInstance$$anon$2.<init>(UnsafeRowSerializer.scala:55)
ERROR TaskSchedulerImpl: Lost executor 6 on 192.168.10.37: remote Rpc client disassociated
INFO TaskSetManager: Re-queueing tasks for 6 from TaskSet 6.0
WARN ReliableDeliverySupervisor: Association with remote system [akka.tcp://[email protected]:42250] has failed, address is now gated for [5000] ms. Reason: [Disassociated]
WARN TaskSetManager: Lost task 3.0 in stage 6.0 (TID 102, 192.168.10.37): ExecutorLostFailure (executor 6 lost)
INFO DAGScheduler: Executor lost: 6 (epoch 8)
INFO BlockManagerMasterEndpoint: Trying to remove executor 6 from BlockManagerMaster.
INFO BlockManagerMasterEndpoint: Removing block manager BlockManagerId(6, 192.168.10.37, 57139)
INFO BlockManagerMaster: Removed 6 successfully in removeExecutor
INFO AppClient$ClientEndpoint: Executor updated: app-20160115142128-0001/6 is now EXITED (Command exited with code 52)
INFO SparkDeploySchedulerBackend: Executor app-20160115142128-0001/6 removed: Command exited with code 52
INFO SparkDeploySchedulerBackend: Asked to remove non-existent executor 6
          org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 6.0 failed 4 times, most recent failure: Lost task 0.3 in stage 6.0 (TID 142, 192.168.10.36): ExecutorLostFailure (executor 4 lost)
WARN TaskSetManager: Lost task 4.1 in stage 6.0 (TID 137, 192.168.10.38): java.lang.OutOfMemoryError: GC overhead limit exceeded

解決辦法:

由於我們在執行Spark任務是,讀取所需要的原資料,資料量太大,導致在Worker上面分配的任務執行資料時所需要的記憶體不夠,直接導致記憶體溢位了,所以我們有必要增加Worker上面的記憶體來滿足程式執行需要。
Spark Streaming或者其他spark任務中,會遇到在Spark中常見的問題,典型如Executor Lost相關的問題(shuffle fetch失敗,Task失敗重試等)。這就意味著發生了記憶體不足或者資料傾斜的問題。這個目前需要考慮如下幾個點以獲得解決方案:

A.相同資源下,增加partition數可以減少記憶體問題。 原因如下:通過增加partition數,每個task要處理的資料少了,同一時間內,所有正在執行的task要處理的數量少了很多,所有Executor佔用的記憶體也變小了。這可以緩解資料傾斜以及記憶體不足的壓力。
B.關注shuffle read階段的並行數。例如reducegroup 之類的函式,其實他們都有第二個引數,並行度(partition數),只是大家一般都不設定。不過出了問題再設定一下,也不錯。
C.給一個Executor核數設定的太多,也就意味著同一時刻,在該Executor的記憶體壓力會更大,GC也會更頻繁。我一般會控制在3個左右。然後通過提高Executor數量來保持資源的總量不變。

16. Spark Streaming 和kafka整合

報錯資訊如下:

  OffsetOutOfRangeException

解決方案:

如果和kafka訊息中介軟體結合使用,請檢查訊息體是否大於預設設定1m,如果大於,則需要設定fetch.message.max.bytes=1m, 這裡需要把值設定大些

17.報錯資訊:

java.io.IOException : Could not locate executable null\bin\winutils.exe in the Hadoop binaries.(spark sql on hive 任務引發HiveContext NullPointerException)

解決辦法:

在開發hive和Spark整合的時候,如果是Windows系統,並且沒有配置HADOOP_HOME的環境變數,那麼可能找不到winutils.exe這個工具,由於使用hive時,對該命令有依賴,所以不要忽視該錯誤,否則將無法建立HiveContext,一直報Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException
因此,解決該辦法有兩個方式

方案A:

把任務打包成jar,上傳到伺服器上面,伺服器是配置過HADOOP_HOME環境變數的,並且不需要依賴winutils,所以只需要通過spark-submit方式提交即可,如:

  spark-submit --class com.pride.hive.HiveOnSparkTest --master spark://bdata4:7077 spark-simple-1.0.jar

方案B:

解決winutils.exe命令不可用問題,配置Windows上面HADOOP_HOME的環境變數,或者在程式最開始的地方設定HADOOP_HOME的屬性配置,這裡需要注意,由於最新版本已經沒有winutils這些exe命令了,我們需要在其他地方下載該命令放入HADOOP的bin目錄下,當然也可以直接配置下載專案的環境變數,變數名一定要是HADOOP_HOME才行

下載地址: (記得FQ哦)
    https://github.com/srccodes/hadoop-common-2.2.0-bin/archive/master.zip

任何專案都生效,需要配置Windows的環境變數,如果只在程式中生效可在程式中配置即可,如:

//用於解決Windows下找不到winutils.exe命令
System. setProperty("hadoop.home.dir", "E:\\Software\\hadoop-common-2.2.0-bin" );

19.報錯資訊:

Exception in thread "main" org.apache.hadoop.security.AccessControlException : Permission denied: user=Administrator, access=WRITE, inode="/data":bdata:supergroup:drwxr-xr-x

解決辦法

1.在系統的環境變數或JVM變數裡面新增HADOOP_USER_NAME,如程式中新增:
System.setProperty("HADOOP_USER_NAME", "bdata");, 這裡的值就是以後會執行HADOOP上的Linux的使用者名稱,如果是eclipse,則修改完重啟eclipse,不然可能不生效
2.修改有問題的目錄許可權

hadoop fs -chmod 755 /tmp

並hive-site.xml檔案中增加以下配置

<property>
    <name>hive.scratch.dir.permission</name>
    <value>755</value>
</property>

20.執行Spark-SQL報錯:

  org.apache.spark.sql.AnalysisException: unresolved operator 'Project

解決辦法:

在Spark-sql和hive結合時或者單獨Spark-sql,執行某些sql語句時,偶爾出現上面錯誤,那麼我們可以檢查一下sql的問題,這裡遇到的問題是巢狀語句太多,導致spark無法解析,所以需要修改sql或者改用其他方式處理;特別注意該語句可能在hive裡面沒有錯誤,spark才會出現的一種錯誤。

21.報錯資訊如下:

org.apache.spark.SparkException: Only one SparkContext may be running in this JVM (see SPARK-2243). To ignore this error, set spark.driver.allowMultipleContexts = true.

解決方案:

使用Use this constructor JavaStreamingContext(sparkContext: JavaSparkContext, batchDuration: Duration)替代 new JavaStreamingContext(sparkConf, Durations.seconds(5))

22.報錯資訊如下:

java.lang.IllegalArgumentException: requirement failed: No output operations registered, so nothing to execute

解決方案:

tranformation最後一步產生的那個RDD必須有相應Action操作,例如massages.print()

23.報錯資訊如下:

ERROR ApplicationMaster: SparkContext did not initialize after waiting for 100000 ms. Please check earlier log output for errors. Failing the application

解決方案:

資源不能分配過大,或者沒有把.setMaster("local[*]")去掉

24.報錯資訊如下:

java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 0

解決方案:

元字元記得轉義

25.報錯資訊如下:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream

解決方案:

編譯spark用了hadoop-provided引數,導致缺少hadoop相關包

26.報錯資訊如下:

org.apache.spark.SparkException: Task failed while writing rows Caused by: org.elasticsearch.hadoop.rest.EsHadoopInvalidRequest: null

解決方案:

ES負載過高,修復ES

27.報錯資訊如下:

org.apache.spark.SparkException: Task failed while writing rows scala.MatchError: Buffer(10.113.80.29, None) (of class scala.collection.convert.Wrappers$JListWrapper)

解決方案:

ES資料在sparksql型別轉化時不相容,可通過EsSpark.esJsonRDD以字串形式取ES資料,再把rdd轉換成dataframe

28.報錯資訊如下:

SparkListenerBus has already stopped! Dropping event SparkListenerStageCompleted

解決方案:

叢集資源不夠,確保真實剩餘記憶體大於spark job申請的記憶體

29.報錯資訊如下:

ExecutorLostFailure (executor 3 exited caused by one of the running tasks) Reason: Container killed by YARN for exceeding memory limits. 61.0 GB of 61 GB physical memory used

解決方案:

配置項spark.storage.memoryFraction預設值為0.6, 應加大spark.storage.memoryFraction的係數

30.問題如下:

如何定位spark的資料傾斜 

解決方案:

Spark Web UI看一下當前stage各個task分配的資料量以及執行時間,根據stage劃分原理定位程式碼中shuffle類運算元

31.報錯資訊如下:

如何解決spark資料傾斜 

解決方案:

  1. 過濾少數導致傾斜的key(僅限於拋棄的Key對作業影響很小)
  2. 提高shuffle操作並行度(提升效果有限)
  3. 兩階段聚合(區域性聚合+全域性聚合),先對相同的key加字首變成多個key,區域性shuffle後再去掉字首,再次進行全域性shuffle(僅適用於聚合類的shuffle操作,效果明顯,對於join類的shuffle操作無效),
  4. reduce join轉為map join,將小表進行廣播,對大表map操作,遍歷小表資料(僅適用於大小表或RDD情況)
  5. 使用隨機字首和擴容RDD進行join,對其中一個RDD每條資料打上n以內的隨機字首,用flatMap運算元對另一個RDD進行n倍擴容並擴容後的每條資料依次打上0~n的字首,最後將兩個改造key後的RDD進行join(能大幅緩解join型別資料傾斜,需要消耗鉅額記憶體)

32.報錯資訊如下:

org.apache.spark.SparkException: Failed to get broadcast_790_piece0 of broadcast_790

解決方案:

刪除spark-defaults.conf檔案中spark.cleaner.ttl的配置

33.報錯資訊如下:

  MapperParsingException[Malformed content, must start with an object

解決方案:

採用介面JavaEsSpark.saveJsonToEs,因為saveToEs只能處理物件不能處理字串

34.報錯資訊如下:

  java.util.concurrent.TimeoutException: Cannot receive any reply in 120 seconds

解決方案:

  1. 確保所有節點之間能夠免密碼登入
  2. 確保所在的主機滿足spark-env.sh中分配的CPU個數,若spark-env.sh中分配的CPU個數為一個,而masterworker在同一部主機上,則該主機需最少分配2個CPU

35.報錯資訊如下:

Exception in thread "main" org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master.

解決方案:

出現此類問題有很多種, 當時遇到這問題的因為是在spark未改動的情況下, 更換了Hive的版本導致版本不對出現了此問題, 解決此問題的方法是:

  1. 再次執行spark計算, 檢視日誌中Hive的版本, 檢查當前Hive是否與Spark日誌中的Hive版本一致
  2. 若Hive版本不一致, 則刪除現有的Hive, 並刪除MySQL中Hive的元資料(若使用MySQL元資料庫), HDFS上hivetmpuser目錄下的資料
  3. 安裝與Spark日誌中版本匹配的Hive

36.EsRejectedExecutionException

error: 
failure in bulk execution:
[4]: index [teacher.tis1.teacher], type [teacher_comment], id [1265687], message [RemoteTransportException[[node-1][192.168.4.30:9300][indices:data/write/bulk[s][p]]]; nested: EsRejectedExecutionException[rejected execution of org.elasticsearch.transport.[email protected] on EsThreadPoolExecutor[bulk, queue capacity = 50, [email protected]160e59[Running, pool size = 4, active threads = 4, queued tasks = 50, completed tasks = 6362]]];]

原因: 說明ES索引資料的速度已經跟不上client端傳送bulk請求的速度,請求佇列已滿以致開始拒絕新的請求。 這是ES叢集的自我保護機制。可以適當睡眠一段時間或者將佇列設定大點。預設設定是 bulk thead pool set queue capacity =50 可以設定大點。

解決辦法:開啟 elasticsearch.yml 在末尾加上 
                       threadpool:
                       bulk:
                       type: fixed
                      size: 60
                      queue_size: 1000
                   重新啟動服務即可


37.DocumentMissingException

error: [[teacher.tis1.teacher/YudbzduURsGhxHMRzyfNcA][[teacher.tis1.teacher][1]] DocumentMissingException[[teacher][344]: document missing]]

原因: 找不到文件,可能是索引(index)或者型別(type)名稱錯誤導致找不到文件,或者文件記錄不存在時更新索引則報錯。比如:更新id為414的記錄,而此時ES中不存在id為414記錄的資料,則丟擲此異常

解決辦法:

1.檢查索引(index)名稱是否正確
2.檢查型別(type)名稱是否正確
3.記錄不存在時更新索引則報錯 可以在更新索引是使用upsert屬性,如果不存在則進行建立。程式碼如下:
IndexRequest indexRequest = new IndexRequest(index, type, id).source(jsonSource);
UpdateRequest updateRequest = new UpdateRequest(index, type, id).doc(jsonSource).upsert(indexRequest);

38.RemoteTransportException:

error: org.elasticsearch.transport.RemoteTransportException: Failed to deserialize exception response from stream

原因: es節點之間的JDK版本不一樣

解決辦法:統一JDK環境

39.NoNodeAvailableException:

error: org.elasticsearch.client.transport.NoNodeAvailableException: No node available

原因: 節點不可用,
(1) es client與java client的版本不一致
(2)埠號錯誤
(3)叢集名字錯誤
(4)jar包引用版本不匹配

解決辦法:

 1.檢查es client與java client的版本是否一致 目前我們專案中使用的是java1.8對應es5.5.2
2.檢查埠號是否正確 使用client連線應使用es的transport 埠號
3.檢查叢集名稱是否正確
4.檢查es與es client的版本號是否一致 目前我們專案中使用的均為5.5.2