一.經驗
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操作的算子有:distinct
, groupByKey
, reduceByKey
, aggregateByKey
, join
, cogroup
, repartition
等
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.instances
, spark.executor.cores
, spark.executor.memory
等配置來優化hive on spark執行性能,不過最好配成動態資源分配。
</br>
</br>
</br>
</br>
二.基本功能
0.常見問題:
1如果運行程序出現錯誤:Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
,這是因爲項目缺少slf4j-api.jar
和slf4j-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)
</br>
</br>
2.啓動spark-shell時,報錯
INFO cluster.YarnClientSchedulerBackend: Registered executor: Actor[akka.tcp://sparkExecutor@services07: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
</br>
</br>
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
</br>
</br>
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的登錄密碼是否一致
</br>
</br>
5.啓動計算任務時報錯:
報錯信息爲:
org.apache.spark.rpc.RpcTimeoutException: Futures timed out after [120 seconds]. This timeout is controlled by spark.rpc.askTimeout
解決方案:
分配的core不夠, 多分配幾核的CPU
</br>
</br>
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.
</br>
</br>
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>
</br>
</br>
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
目錄下
</br>
</br>
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)
</br>
</br>
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
</br>
</br>
</br>
</br>
三.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狀態
</br>
</br>
2.問題出現情景:
Spakr集羣的所有運行數據在Master重啓是都會丟失
解決方案:
配置spark.deploy.recoveryMode
選項爲ZOOKEEPER
</br>
</br>
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
</br>
</br>
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
</br>
</br>
5.問題出現情景:
Worker節點中的work目錄佔用許多磁盤空間, 這些是Driver上傳到worker的文件, 會佔用許多磁盤空間.
解決方案:
需要定時做手工清理. 目錄地址:/home/centos/soft/spark/work
</br>
</br>
6.問題出現情景:
spark-shell
提交Spark Application
如何解決依賴庫
解決方案:
利用--driver-class-path
選項來指定所依賴的jar文件,注意的是--driver-class-path
後如果需要跟着多個jar文件的話,jar文件之間使用冒號:
來分割。
</br>
</br>
7.Spark在發佈應用的時候,出現連接不上master
報錯信息如下:
INFO AppClient$ClientEndpoint: Connecting to master spark://s1:7077...
WARN ReliableDeliverySupervisor: Association with remote system [akka.tcp://sparkMaster@s1:7077] has failed, address is now gated for [5000] ms. Reason: [Disassociated]
解決方案:
檢查所有機器時間是否一致.hosts是否都配置了映射.客戶端和服務器端的Scala版本是否一致.Scala版本是否和Spark兼容
</br>
</br>
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
,重新發布,有一定機率發佈成功。
</br>
</br>
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數據庫即可
</br>
</br>
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
</br>
</br>
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
</br>
</br>
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)
解決方案:
這裏遇到的問題主要是因爲數據源數據量過大,而機器的內存無法滿足需求,導致長時間執行超時斷開的情況,數據無法有效進行交互計算,因此有必要增加內存
</br>
</br>
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
設置的內存過大,已經超過了實際機器擁有的內存,故無法執行,需要等待機器擁有足夠的內存後,才能執行任務,可以減少任務執行內存,設置小一些即可
</br>
</br>
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
階段的並行數。例如reduce
, group
之類的函數,其實他們都有第二個參數,並行度(partition
數),只是大家一般都不設置。不過出了問題再設置一下,也不錯。
C.給一個Executor
核數設置的太多,也就意味着同一時刻,在該Executor
的內存壓力會更大,GC
也會更頻繁。我一般會控制在3
個左右。然後通過提高Executor
數量來保持資源的總量不變。
</br>
</br>
16. Spark Streaming 和kafka整合
報錯信息如下:
OffsetOutOfRangeException
解決方案:
如果和kafka消息中間件結合使用,請檢查消息體是否大於默認設置1m
,如果大於,則需要設置fetch.message.max.bytes=1m
, 這裏需要把值設置大些
</br>
</br>
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才行
下載地址: (記得翻牆哦)
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" );
</br>
</br>
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>
</br>
</br>
20.運行Spark-SQL報錯:
org.apache.spark.sql.AnalysisException: unresolved operator 'Project
解決辦法:
在Spark-sql和hive結合時或者單獨Spark-sql,運行某些sql語句時,偶爾出現上面錯誤,那麼我們可以檢查一下sql的問題,這裏遇到的問題是嵌套語句太多,導致spark無法解析,所以需要修改sql或者改用其他方式處理;特別注意該語句可能在hive裏面沒有錯誤,spark纔會出現的一種錯誤。
</br>
</br>
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))
</br>
</br>
22.報錯信息如下:
java.lang.IllegalArgumentException: requirement failed: No output operations registered, so nothing to execute
解決方案:
tranformation
最後一步產生的那個RDD必須有相應Action操作,例如massages.print()
等
</br>
</br>
23.報錯信息如下:
ERROR ApplicationMaster: SparkContext did not initialize after waiting for 100000 ms. Please check earlier log output for errors. Failing the application
解決方案:
資源不能分配過大,或者沒有把.setMaster("local[*]")
去掉
</br>
</br>
24.報錯信息如下:
java.util.regex.PatternSyntaxException: Dangling meta character '?' near index 0
解決方案:
元字符記得轉義
</br>
</br>
25.報錯信息如下:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream
解決方案:
編譯spark用了hadoop-provided
參數,導致缺少hadoop相關包
</br>
</br>
26.報錯信息如下:
org.apache.spark.SparkException: Task failed while writing rows Caused by: org.elasticsearch.hadoop.rest.EsHadoopInvalidRequest: null
解決方案:
ES負載過高,修復ES
</br>
</br>
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
</br>
</br>
28.報錯信息如下:
SparkListenerBus has already stopped! Dropping event SparkListenerStageCompleted
解決方案:
集羣資源不夠,確保真實剩餘內存大於spark job
申請的內存
</br>
</br>
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
的係數
</br>
</br>
30.問題如下:
如何定位spark的數據傾斜
解決方案:
在Spark Web UI
看一下當前stage各個task分配的數據量以及執行時間,根據stage劃分原理定位代碼中shuffle
類算子
</br>
</br>
31.報錯信息如下:
如何解決spark數據傾斜
解決方案:
- 過濾少數導致傾斜的key(僅限於拋棄的Key對作業影響很小)
- 提高
shuffle
操作並行度(提升效果有限) - 兩階段聚合(局部聚合+全局聚合),先對相同的key加前綴變成多個key,局部
shuffle
後再去掉前綴,再次進行全局shuffle
(僅適用於聚合類的shuffle
操作,效果明顯,對於join類的shuffle
操作無效), - 將
reduce join
轉爲map join
,將小表進行廣播,對大表map操作,遍歷小表數據(僅適用於大小表或RDD情況) - 使用隨機前綴和擴容RDD進行
join
,對其中一個RDD每條數據打上n
以內的隨機前綴,用flatMap
算子對另一個RDD進行n倍擴容並擴容後的每條數據依次打上0~n的前綴,最後將兩個改造key
後的RDD進行join(能大幅緩解join類型數據傾斜,需要消耗鉅額內存)
</br>
</br>
32.報錯信息如下:
org.apache.spark.SparkException: Failed to get broadcast_790_piece0 of broadcast_790
解決方案:
刪除spark-defaults.conf
文件中spark.cleaner.ttl
的配置
</br>
</br>
33.報錯信息如下:
MapperParsingException[Malformed content, must start with an object
解決方案:
採用接口JavaEsSpark.saveJsonToEs
,因爲saveToEs
只能處理對象不能處理字符串
</br>
</br>
34.報錯信息如下:
java.util.concurrent.TimeoutException: Cannot receive any reply in 120 seconds
解決方案:
- 確保所有節點之間能夠免密碼登錄
- 確保所在的主機滿足
spark-env.sh
中分配的CPU個數,若spark-env.sh
中分配的CPU個數爲一個,而master
和worker
在同一部主機上,則該主機需最少分配2個CPU
</br>
</br>
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的版本導致版本不對出現了此問題, 解決此問題的方法是:
- 再次運行spark計算, 查看日誌中Hive的版本, 檢查當前Hive是否與Spark日誌中的Hive版本一致
- 若Hive版本不一致, 則刪除現有的Hive, 並刪除MySQL中Hive的元數據(若使用MySQL元數據庫), HDFS上
hive
,tmp
,user
目錄下的數據 - 安裝與Spark日誌中版本匹配的Hive