搭建Spark所遇過的坑

大數(shù)據(jù)

作者:花弄影

一.經(jīng)驗(yàn)

Spark Streaming包含三種計(jì)算模式:nonstate .stateful .windowkafka可通過配置文件使用自帶的zookeeper集群Spark一切操作歸根結(jié)底是對(duì)RDD的操作部署Spark任務(wù),不用拷貝整個(gè)架包,只需拷貝被修改的文件,然后在目標(biāo)服務(wù)器上編譯打包。kafka的log.dirs不要設(shè)置成/tmp下的目錄,貌似tmp目錄有文件數(shù)和磁盤容量限制ES的分片類似kafka的partitionspark Graph根據(jù)邊集合構(gòu)建圖,頂點(diǎn)集合只是指定圖中哪些頂點(diǎn)有效presto集群沒必要采用on yarn模式,因?yàn)閔adoop依賴HDFS,如果部分機(jī)器磁盤很小,hadoop會(huì)很尷尬,而presto是純內(nèi)存計(jì)算,不依賴磁盤,獨(dú)立安裝可以跨越多個(gè)集群,可以說有內(nèi)存的地方就可以有prestopresto進(jìn)程一旦啟動(dòng),JVM server會(huì)一直占用內(nèi)存如果maven下載很慢,很可能是被天朝的GFW墻了,可以在maven安裝目錄的setting.conf配置文件mirrors標(biāo)簽下加入國(guó)內(nèi)鏡像抵制**黨的網(wǎng)絡(luò)封鎖,例如:
<mirror> ?<id>nexus-aliyun</id> ?<mirrorOf>*</mirrorOf> ?<name>Nexus aliyun</name> ?<url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror>
編譯spark,hive on spark就不要加-Phive參數(shù),若需sparkSQL支持hive語法則要加-Phive參數(shù)通過hive源文件pom.xml查看適配的spark版本,只要打版本保持一致就行,例如spark1.6.0和1.6.2都能匹配打開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有沒有綁定sparkkafka的comsumer groupID對(duì)于spark direct streaming無效shuffle write就是在一個(gè)stage結(jié)束計(jì)算之后,為了下一個(gè)stage可以執(zhí)行shuffle類的算子,而將每個(gè)task處理的數(shù)據(jù)按key進(jìn)行分類,將相同key都寫入同一個(gè)磁盤文件中,而每一個(gè)磁盤文件都只屬于下游stage的一個(gè)task,在將數(shù)據(jù)寫入磁盤之前,會(huì)先將數(shù)據(jù)寫入內(nèi)存緩存中,下一個(gè)stage的task有多少個(gè),當(dāng)前stage的每個(gè)task就要?jiǎng)?chuàng)建多少份磁盤文件。單個(gè)spark任務(wù)的excutor核數(shù)不宜設(shè)置過高,否則會(huì)導(dǎo)致其他JOB延遲數(shù)據(jù)傾斜只發(fā)生在shuffle過程,可能觸發(fā)shuffle操作的算子有:distinct,??groupByKey,??reduceByKey,??aggregateByKey,??join,??cogroup,??repartition等運(yùn)行時(shí)刪除hadoop數(shù)據(jù)目錄會(huì)導(dǎo)致依賴HDFS的JOB失效sparkSQL UDAF中update函數(shù)的第二個(gè)參數(shù) input: Row 對(duì)應(yīng)的并非DataFrame的行,而是被inputSchema投影了的行Spark的Driver只有在Action時(shí)才會(huì)收到結(jié)果Spark需要全局聚合變量時(shí)應(yīng)當(dāng)使用累加器(Accumulator)Kafka以topic與consumer group劃分關(guān)系,一個(gè)topic的消息會(huì)被訂閱它的消費(fèi)者組全部消費(fèi),如果希望某個(gè)consumer使用topic的全部消息,可將該組只設(shè)一個(gè)消費(fèi)者,每個(gè)組的消費(fèi)者數(shù)目不能大于topic的partition總數(shù),否則多出的consumer將無消可費(fèi)所有自定義類要實(shí)現(xiàn)serializable接口,否則在集群中無法生效resources資源文件讀取要在Spark Driver端進(jìn)行,以局部變量方式傳給閉包函數(shù)DStream流轉(zhuǎn)化只產(chǎn)生臨時(shí)流對(duì)象,如果要繼續(xù)使用,需要一個(gè)引用指向該臨時(shí)流對(duì)象提交到y(tǒng)arn cluster的作業(yè)不能直接print到控制臺(tái),要用log4j輸出到日志文件中HDFS文件路徑寫法為:hdfs://master:9000/文件路徑,這里的master是namenode的hostname,9000是hdfs端口號(hào)。不要隨意格式化HDFS,這會(huì)帶來數(shù)據(jù)版本不一致等諸多問題,格式化前要清空數(shù)據(jù)文件夾搭建集群時(shí)要首先配置好主機(jī)名,并重啟機(jī)器讓配置的主機(jī)名生效linux批量多機(jī)互信, 將pub秘鑰配成一個(gè)小于128M的小文件都會(huì)占據(jù)一個(gè)128M的BLOCK,合并或者刪除小文件節(jié)省磁盤空間Non DFS Used指的是非HDFS的所有文件spark兩個(gè)分區(qū)方法coalesce和repartition,前者窄依賴,分區(qū)后數(shù)據(jù)不均勻,后者寬依賴,引發(fā)shuffle操作,分區(qū)后數(shù)據(jù)均勻spark中數(shù)據(jù)寫入ElasticSearch的操作必須在action中以RDD為單位執(zhí)行可以通過hive-site.xml修改spark.executor.instances,?spark.executor.cores,?spark.executor.memory等配置來優(yōu)化hive on spark執(zhí)行性能,不過最好配成動(dòng)態(tài)資源分配。

二.基本功能

0.常見問題:

1如果運(yùn)行程序出現(xiàn)錯(cuò)誤:Exception in thread “main” java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory,這是因?yàn)轫?xiàng)目缺少slf4j-api.jar和slf4j-log4j12.jar這兩個(gè)jar包導(dǎo)致的錯(cuò)誤。 2如果運(yùn)行程序出現(xiàn)錯(cuò)誤:java.lang.NoClassDefFoundError: org/apache/log4j/LogManager,這是因?yàn)轫?xiàng)目缺少log4j.jar這個(gè)jar包 3錯(cuò)誤:Exception in thread “main” java.lang.NoSuchMethodError: org.slf4j.MDC.getCopyOfContextMap()Ljava/util/Map,這是因?yàn)閖ar包版本沖突造成的。

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.啟動(dòng)spark-shell時(shí),報(bào)錯(cuò)

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

解決方案:

在spark的spark-env配置文件中配置下列配置項(xiàng):

將export SPARK_WORKER_MEMORY, export SPARK_DRIVER_MEMORY, export SPARK_YARN_AM_MEMORY的值設(shè)置成小于534.5 MB

3.啟動(dòng)spark SQL時(shí),報(bào)錯(cuò):

 ?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.啟動(dòng)spark SQL時(shí),報(bào)錯(cuò):

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

解決方案:

檢查hive-site.xml的配置項(xiàng), 有以下這個(gè)配置項(xiàng)

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

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

5.啟動(dòng)計(jì)算任務(wù)時(shí)報(bào)錯(cuò):

報(bào)錯(cuò)信息為:

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

解決方案:

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

6.啟動(dòng)計(jì)算任務(wù)時(shí)報(bào)錯(cuò):

不斷重復(fù)出現(xiàn)

 ?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

解決方案:

 ? ?資源不夠, 分配大點(diǎn)內(nèi)存, 默認(rèn)值為512MB.

7.啟動(dòng)Spark作為計(jì)算引擎時(shí)報(bào)錯(cuò):

報(bào)錯(cuò)信息為:

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.

解決方案:

出現(xiàn)該問題的原因有多種, 我所遇到的是使用Hive On Spark時(shí)報(bào)了此錯(cuò)誤,解決方案是: 在hive-site.xml文件下正確配置該項(xiàng)

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

8.啟動(dòng)spark集群時(shí)報(bào)錯(cuò),啟動(dòng)命令為:start-mastersh

報(bào)錯(cuò)信息:

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.啟動(dòng)spark集群時(shí)報(bào)錯(cuò),啟動(dòng)命令為:start-mastersh

報(bào)錯(cuò)信息:

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

解決方案:

官網(wǎng)資料: ? ?https://spark.apache.org/docs/latest/hadoop-provided.html#apache-hadoop

編輯/home/centos/soft/spark/conf/spark-env.sh文件,配置下列配置項(xiàng):

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

10.啟動(dòng)HPL/SQL存儲(chǔ)過程時(shí)報(bào)錯(cuò):

報(bào)錯(cuò)信息:

2017-01-10T15:20:18,491 ERROR [HiveServer2-Background-Pool: Thread-97] exec.TaskRunner: Error in executeTaskjava.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 space2017-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 seconds2017-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

出現(xiàn)該問題是因?yàn)镾park默認(rèn)使用全部資源, 而此時(shí)主機(jī)的內(nèi)存已用, 應(yīng)在Spark配置文件中限制內(nèi)存的大小. 在hive-site.xml文件下配置該項(xiàng):

<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.報(bào)錯(cuò)信息:

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

解決方案:

查看執(zhí)行Spark計(jì)算的是否處于standby狀態(tài), 用瀏覽器訪問該主機(jī):http://m1:50070, 如果處于standby狀態(tài), 則不可在處于StandBy機(jī)器運(yùn)行spark計(jì)算,應(yīng)切執(zhí)行Spark計(jì)算的主機(jī)從Standby狀態(tài)切換到Active狀態(tài)

2.問題出現(xiàn)情景:

Spakr集群的所有運(yùn)行數(shù)據(jù)在Master重啟是都會(huì)丟失

解決方案:

配置spark.deploy.recoveryMode選項(xiàng)為ZOOKEEPER

3.報(bào)錯(cuò)信息:

由于Spark在計(jì)算的時(shí)候會(huì)將中間結(jié)果存儲(chǔ)到/tmp目錄,而目前l(fā)inux又都支持tmpfs,其實(shí)就是將/tmp目錄掛載到內(nèi)存當(dāng)中, 那么這里就存在一個(gè)問題,中間結(jié)果過多導(dǎo)致/tmp目錄寫滿而出現(xiàn)如下錯(cuò)誤

No Space Left on the device(Shuffle臨時(shí)文件過多)

解決辦法:

修改配置文件spark-env.sh,把臨時(shí)文件引入到一個(gè)自定義的目錄中去, 即:

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

4.報(bào)錯(cuò)信息:

java.lang.OutOfMemory, unable to create new native threadCaused 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)

解決方案:

上面這段錯(cuò)誤提示的本質(zhì)是Linux操作系統(tǒng)無法創(chuàng)建更多進(jìn)程,導(dǎo)致出錯(cuò),并不是系統(tǒng)的內(nèi)存不足。因此要解決這個(gè)問題需要修改Linux允許創(chuàng)建更多的進(jìn)程,就需要修改Linux最大進(jìn)程數(shù)。 (1)修改Linux最大進(jìn)程數(shù)

ulimit -a

(2)臨時(shí)修改允許打開的最大進(jìn)程數(shù)

ulimit -u 65535

(3)臨時(shí)修改允許打開的文件句柄

ulimit -n 65535

(4)永久修改Linux最大進(jìn)程數(shù)量

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

永久修改用戶打開文件的最大句柄數(shù),該值默認(rèn)1024,一般都會(huì)不夠,常見錯(cuò)誤就是not open file?解決辦法:

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

5.問題出現(xiàn)情景:

Worker節(jié)點(diǎn)中的work目錄占用許多磁盤空間, 這些是Driver上傳到worker的文件, 會(huì)占用許多磁盤空間.

解決方案:

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

6.問題出現(xiàn)情景:

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

解決方案:

利用–driver-class-path選項(xiàng)來指定所依賴的jar文件,注意的是–driver-class-path后如果需要跟著多個(gè)jar文件的話,jar文件之間使用冒號(hào):來分割。

7.Spark在發(fā)布應(yīng)用的時(shí)候,出現(xiàn)連接不上master

報(bào)錯(cuò)信息如下:

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]

解決方案:

檢查所有機(jī)器時(shí)間是否一致.hosts是否都配置了映射.客戶端和服務(wù)器端的Scala版本是否一致.Scala版本是否和Spark兼容

8.開發(fā)spark應(yīng)用程序(和Flume-NG結(jié)合時(shí))發(fā)布應(yīng)用時(shí)可能會(huì)報(bào)錯(cuò)

報(bào)錯(cuò)信息如下:

ERROR ReceiverSupervisorImpl: Stopped receiver with error: org.jboss.netty.channel.ChannelException: Failed to bind to: /192.168.10.156:18800ERROR 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發(fā)布的時(shí)候,會(huì)自動(dòng)選取發(fā)送到某一臺(tái)的worker節(jié)點(diǎn)上,所以這里綁定端口的時(shí)候,需要選擇相應(yīng)的worker服務(wù)器,但是由于我們無法事先了解到,spark發(fā)布到哪一臺(tái)服務(wù)器的,所以這里啟動(dòng)報(bào)錯(cuò),是因?yàn)樵?92.168.10.156:18800的機(jī)器上面沒有啟動(dòng)Driver程序,而是發(fā)布到了其他服務(wù)器去啟動(dòng)了,所以無法監(jiān)聽到該機(jī)器出現(xiàn)問題,所以我們需要設(shè)置spark分發(fā)包時(shí),發(fā)布到所有worker節(jié)點(diǎn)機(jī)器,或者發(fā)布后,我們?nèi)ふ野l(fā)布到了哪一臺(tái)機(jī)器,重新修改綁定IP,重新發(fā)布,有一定幾率發(fā)布成功。

9.使用Hive on Spark時(shí)報(bào)錯(cuò):

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

解決方案:

在使用Hive on Spark模式操作hive里面的數(shù)據(jù)時(shí),報(bào)以上錯(cuò)誤,原因是因?yàn)镠IVE采用了derby這個(gè)內(nèi)嵌數(shù)據(jù)庫作為數(shù)據(jù)庫,它不支持多用戶同時(shí)訪問,解決辦法就是把derby數(shù)據(jù)庫換成mysql數(shù)據(jù)庫即可

10.找不到hdfs集群名字dfscluster

報(bào)錯(cuò)信息:

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

解決辦法:

將$HADOOP_HOME/etc/hadoop/hdfs-site.xml文件拷貝到Spark集群的所有主機(jī)的$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.在執(zhí)行yarn集群或者客戶端時(shí),報(bào)錯(cuò):

執(zhí)行指令:

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

報(bào)如下錯(cuò)誤:

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.

解決辦法:

根據(jù)提示,配置HADOOP_CONF_DIR?or?YARN_CONF_DIR的環(huán)境變量即可, 在spark-env.sh文件中配置以下幾項(xiàng):

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

12.提交spark計(jì)算任務(wù)時(shí),報(bào)錯(cuò):

報(bào)錯(cuò)信息如下:

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 jobException 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)

解決方案:

這里遇到的問題主要是因?yàn)閿?shù)據(jù)源數(shù)據(jù)量過大,而機(jī)器的內(nèi)存無法滿足需求,導(dǎo)致長(zhǎng)時(shí)間執(zhí)行超時(shí)斷開的情況,數(shù)據(jù)無法有效進(jìn)行交互計(jì)算,因此有必要增加內(nèi)存

13.啟動(dòng)Spark計(jì)算任務(wù):

長(zhǎng)時(shí)間等待無反應(yīng),并且看到服務(wù)器上面的web界面有內(nèi)存和核心數(shù),但是沒有分配,報(bào)錯(cuò)信息如下:

status.SparkJobMonitor: 2017-01-04 11:53:51,564 ? ?Stage-0_0: 0(+1)/1status.SparkJobMonitor: 2017-01-04 11:53:51,564 ? ?Stage-0_0: 0(+1)/1status.SparkJobMonitor: 2017-01-04 11:53:51,564 ? ?Stage-0_0: 0(+1)/1status.SparkJobMonitor: 2017-01-04 11:53:51,564 ? ?Stage-0_0: 0(+1)/1status.SparkJobMonitor: 2017-01-04 11:53:51,564 ? ?Stage-0_0: 0(+1)/1status.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

解決方案:

出現(xiàn)上面的問題主要原因是因?yàn)槲覀兺ㄟ^參數(shù)spark.executor.memory設(shè)置的內(nèi)存過大,已經(jīng)超過了實(shí)際機(jī)器擁有的內(nèi)存,故無法執(zhí)行,需要等待機(jī)器擁有足夠的內(nèi)存后,才能執(zhí)行任務(wù),可以減少任務(wù)執(zhí)行內(nèi)存,設(shè)置小一些即可

14.內(nèi)存不足或數(shù)據(jù)傾斜導(dǎo)致Executor Lost(spark-submit提交)

報(bào)錯(cuò)信息如下:

TaskSetManager: Lost task 1.0 in stage 6.0 (TID 100, 192.168.10.37): java.lang.OutOfMemoryError: Java heap spaceINFO 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 disassociatedINFO TaskSetManager: Re-queueing tasks for 6 from TaskSet 6.0WARN ReliableDeliverySupervisor: Association with remote system [akka.tcp://sparkExecutor@192.168.10.37: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 removeExecutorINFO 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 52INFO 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

解決辦法:

由于我們?cè)趫?zhí)行Spark任務(wù)是,讀取所需要的原數(shù)據(jù),數(shù)據(jù)量太大,導(dǎo)致在Worker上面分配的任務(wù)執(zhí)行數(shù)據(jù)時(shí)所需要的內(nèi)存不夠,直接導(dǎo)致內(nèi)存溢出了,所以我們有必要增加Worker上面的內(nèi)存來滿足程序運(yùn)行需要。 在Spark Streaming或者其他spark任務(wù)中,會(huì)遇到在Spark中常見的問題,典型如Executor Lost相關(guān)的問題(shuffle fetch失敗,Task失敗重試等)。這就意味著發(fā)生了內(nèi)存不足或者數(shù)據(jù)傾斜的問題。這個(gè)目前需要考慮如下幾個(gè)點(diǎn)以獲得解決方案:

A.相同資源下,增加partition數(shù)可以減少內(nèi)存問題。 原因如下:通過增加partition數(shù),每個(gè)task要處理的數(shù)據(jù)少了,同一時(shí)間內(nèi),所有正在運(yùn)行的task要處理的數(shù)量少了很多,所有Executor占用的內(nèi)存也變小了。這可以緩解數(shù)據(jù)傾斜以及內(nèi)存不足的壓力。 B.關(guān)注shuffle read階段的并行數(shù)。例如reduce,?group?之類的函數(shù),其實(shí)他們都有第二個(gè)參數(shù),并行度(partition數(shù)),只是大家一般都不設(shè)置。不過出了問題再設(shè)置一下,也不錯(cuò)。 C.給一個(gè)Executor核數(shù)設(shè)置的太多,也就意味著同一時(shí)刻,在該Executor的內(nèi)存壓力會(huì)更大,GC也會(huì)更頻繁。我一般會(huì)控制在3個(gè)左右。然后通過提高Executor數(shù)量來保持資源的總量不變。

16. Spark Streaming 和kafka整合

報(bào)錯(cuò)信息如下:

 ?OffsetOutOfRangeException

解決方案:

如果和kafka消息中間件結(jié)合使用,請(qǐng)檢查消息體是否大于默認(rèn)設(shè)置1m,如果大于,則需要設(shè)置fetch.message.max.bytes=1m, 這里需要把值設(shè)置大些

17.報(bào)錯(cuò)信息:

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

解決辦法:

在開發(fā)hive和Spark整合的時(shí)候,如果是Windows系統(tǒng),并且沒有配置HADOOP_HOME的環(huán)境變量,那么可能找不到winutils.exe這個(gè)工具,由于使用hive時(shí),對(duì)該命令有依賴,所以不要忽視該錯(cuò)誤,否則將無法創(chuàng)建HiveContext,一直報(bào)Exception in thread “main” java.lang.RuntimeException: java.lang.NullPointerException?因此,解決該辦法有兩個(gè)方式

方案A:

把任務(wù)打包成jar,上傳到服務(wù)器上面,服務(wù)器是配置過HADOOP_HOME環(huán)境變量的,并且不需要依賴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的環(huán)境變量,或者在程序最開始的地方設(shè)置HADOOP_HOME的屬性配置,這里需要注意,由于最新版本已經(jīng)沒有winutils這些exe命令了,我們需要在其他地方下載該命令放入HADOOP的bin目錄下,當(dāng)然也可以直接配置下載項(xiàng)目的環(huán)境變量,變量名一定要是HADOOP_HOME才行

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

任何項(xiàng)目都生效,需要配置Windows的環(huán)境變量,如果只在程序中生效可在程序中配置即可,如:

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

19.報(bào)錯(cuò)信息:

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

解決辦法

1.在系統(tǒng)的環(huán)境變量或JVM變量里面添加HADOOP_USER_NAME,如程序中添加:?System.setProperty(“HADOOP_USER_NAME”, “bdata”);, 這里的值就是以后會(huì)運(yùn)行HADOOP上的Linux的用戶名,如果是eclipse,則修改完重啟eclipse,不然可能不生效 2.修改有問題的目錄權(quán)限

hadoop fs -chmod 755 /tmp

并hive-site.xml文件中增加以下配置

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

20.運(yùn)行Spark-SQL報(bào)錯(cuò):

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

解決辦法:

在Spark-sql和hive結(jié)合時(shí)或者單獨(dú)Spark-sql,運(yùn)行某些sql語句時(shí),偶爾出現(xiàn)上面錯(cuò)誤,那么我們可以檢查一下sql的問題,這里遇到的問題是嵌套語句太多,導(dǎo)致spark無法解析,所以需要修改sql或者改用其他方式處理;特別注意該語句可能在hive里面沒有錯(cuò)誤,spark才會(huì)出現(xiàn)的一種錯(cuò)誤。

21.報(bào)錯(cuò)信息如下:

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.報(bào)錯(cuò)信息如下:

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

解決方案:

tranformation最后一步產(chǎn)生的那個(gè)RDD必須有相應(yīng)Action操作,例如massages.print()等

23.報(bào)錯(cuò)信息如下:

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

解決方案:

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

24.報(bào)錯(cuò)信息如下:

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

解決方案:

元字符記得轉(zhuǎn)義

25.報(bào)錯(cuò)信息如下:

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

解決方案:

編譯spark用了hadoop-provided參數(shù),導(dǎo)致缺少hadoop相關(guān)包

26.報(bào)錯(cuò)信息如下:

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

解決方案:

ES負(fù)載過高,修復(fù)ES

27.報(bào)錯(cuò)信息如下:

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數(shù)據(jù)在sparksql類型轉(zhuǎn)化時(shí)不兼容,可通過EsSpark.esJsonRDD以字符串形式取ES數(shù)據(jù),再把rdd轉(zhuǎn)換成dataframe

28.報(bào)錯(cuò)信息如下:

SparkListenerBus has already stopped! Dropping event SparkListenerStageCompleted

解決方案:

集群資源不夠,確保真實(shí)剩余內(nèi)存大于spark job申請(qǐng)的內(nèi)存

29.報(bào)錯(cuò)信息如下:

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

解決方案:

配置項(xiàng)spark.storage.memoryFraction默認(rèn)值為0.6, 應(yīng)加大spark.storage.memoryFraction的系數(shù)

30.問題如下:

如何定位spark的數(shù)據(jù)傾斜

解決方案:

在Spark Web UI看一下當(dāng)前stage各個(gè)task分配的數(shù)據(jù)量以及執(zhí)行時(shí)間,根據(jù)stage劃分原理定位代碼中shuffle類算子

31.報(bào)錯(cuò)信息如下:

如何解決spark數(shù)據(jù)傾斜

解決方案:

過濾少數(shù)導(dǎo)致傾斜的key(僅限于拋棄的Key對(duì)作業(yè)影響很?。┨岣遱huffle操作并行度(提升效果有限)兩階段聚合(局部聚合+全局聚合),先對(duì)相同的key加前綴變成多個(gè)key,局部shuffle后再去掉前綴,再次進(jìn)行全局shuffle(僅適用于聚合類的shuffle操作,效果明顯,對(duì)于join類的shuffle操作無效),將reduce join轉(zhuǎn)為map join,將小表進(jìn)行廣播,對(duì)大表map操作,遍歷小表數(shù)據(jù)(僅適用于大小表或RDD情況)使用隨機(jī)前綴和擴(kuò)容RDD進(jìn)行join,對(duì)其中一個(gè)RDD每條數(shù)據(jù)打上n以內(nèi)的隨機(jī)前綴,用flatMap算子對(duì)另一個(gè)RDD進(jìn)行n倍擴(kuò)容并擴(kuò)容后的每條數(shù)據(jù)依次打上0~n的前綴,最后將兩個(gè)改造key后的RDD進(jìn)行join(能大幅緩解join類型數(shù)據(jù)傾斜,需要消耗巨額內(nèi)存)

32.報(bào)錯(cuò)信息如下:

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

解決方案:

刪除spark-defaults.conf文件中spark.cleaner.ttl的配置

33.報(bào)錯(cuò)信息如下:

 ?MapperParsingException[Malformed content, must start with an object

解決方案:

采用接口JavaEsSpark.saveJsonToEs,因?yàn)閟aveToEs只能處理對(duì)象不能處理字符串

34.報(bào)錯(cuò)信息如下:

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

解決方案:

確保所有節(jié)點(diǎn)之間能夠免密碼登錄確保所在的主機(jī)滿足spark-env.sh中分配的CPU個(gè)數(shù),若spark-env.sh中分配的CPU個(gè)數(shù)為一個(gè),而master和worker在同一部主機(jī)上,則該主機(jī)需最少分配2個(gè)CPU

35.報(bào)錯(cuò)信息如下:

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

解決方案:

出現(xiàn)此類問題有很多種, 當(dāng)時(shí)遇到這問題的因?yàn)槭窃趕park未改動(dòng)的情況下, 更換了Hive的版本導(dǎo)致版本不對(duì)出現(xiàn)了此問題, 解決此問題的方法是:

再次運(yùn)行spark計(jì)算, 查看日志中Hive的版本, 檢查當(dāng)前Hive是否與Spark日志中的Hive版本一致若Hive版本不一致, 則刪除現(xiàn)有的Hive, 并刪除MySQL中Hive的元數(shù)據(jù)(若使用MySQL元數(shù)據(jù)庫), HDFS上hive,?tmp,?user目錄下的數(shù)據(jù)安裝與Spark日志中版本匹配的Hive\

極客網(wǎng)企業(yè)會(huì)員

免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會(huì)依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

2017-11-09
搭建Spark所遇過的坑
作者:花弄影 一 經(jīng)驗(yàn) Spark Streaming包含三種計(jì)算模式:nonstate stateful window kafka可通過配置文件

長(zhǎng)按掃碼 閱讀全文