scala spark程式設計常見問題總結
阿新 • • 發佈:2018-12-25
問題:ERROR ActorSystemImpl: Uncaught fatal error from thread [sparkDriver-akka.remote.default-remote-dispatcher-8] shutting down ActorSystem [sparkDriver]
15/07/28 13:46:59 ERROR ActorSystemImpl: Uncaught fatal error from thread [sparkDriver-akka.remote.default-remote-dispatcher-8] shutting down ActorSystem [sparkDriver]
java.lang.OutOfMemoryError: Java heap space
at org.spark_project.protobuf.ByteString.toByteArray(ByteString.java:515)
at akka.remote.serialization.MessageContainerSerializer.fromBinary(MessageContainerSerializer.scala:64)
at akka.serialization.Serialization$$anonfun$deserialize$1.apply(Serialization.scala:104)
at scala.util .Try$.apply(Try.scala:161)
at akka.serialization.Serialization.deserialize(Serialization.scala:98)
at akka.remote.MessageSerializer$.deserialize(MessageSerializer.scala:23)
at akka.remote.DefaultMessageDispatcher.payload$lzycompute$1(Endpoint.scala:58)
at akka.remote.DefaultMessageDispatcher .payload$1(Endpoint.scala:58)
at akka.remote.DefaultMessageDispatcher.dispatch(Endpoint.scala:76)
at akka.remote.EndpointReader$$anonfun$receive$2.applyOrElse(Endpoint.scala:937)
at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
at akka.remote.EndpointActor.aroundReceive(Endpoint.scala:415)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
at akka.dispatch.Mailbox.run(Mailbox.scala:220)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
由於叢集較小,只有4臺機器,在其中master上面提交了任務,結果出現上述異常。即driver 記憶體不足,因此使用spark-sumbit指令碼時,提供–executor-memory –driver-memory選項,來相應的設定記憶體。
問題:空指標異常
導致這個問題的原因有很多,和spark本身相關的主要有兩種情況:
- 巢狀使用了RDD操作,比如在一個RDD map中又對另一個RDD進行了map操作。主要原因在於spark不支援RDD的巢狀操作。
- 在RDD操作中引用了object非原始型別(非int long等簡單型別)的成員變數。貌似是由於object的成員變數預設是無法序列化的。解決方法:可以先將成員變數賦值給一個臨時變數,然後使用該臨時變數即可
調整分割槽數的重要性
剛開始執行的時候,預設分割槽數為2,結果在叢集上面執行的時間甚至比本地都慢。通過Web UI檢視任務狀態,如下圖:
可以看到每個stage只有2個task,4個executor實際上只有兩個參與了運算,並行度真是夠低的。
調整方式:在用textFile函式讀取檔案的時候指定分割槽數,由於叢集中有4個executor,而分割槽數最好是executor數量的整數倍,因此將分割槽數指定為8,調整後,結果如下所示:
可見4個executor都參與了運算,並行度有了顯著提升。