1. 程式人生 > >scala spark程式設計常見問題總結

scala spark程式設計常見問題總結

問題: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本身相關的主要有兩種情況:

  1. 巢狀使用了RDD操作,比如在一個RDD map中又對另一個RDD進行了map操作。主要原因在於spark不支援RDD的巢狀操作。
  2. 在RDD操作中引用了object非原始型別(非int long等簡單型別)的成員變數。貌似是由於object的成員變數預設是無法序列化的。解決方法:可以先將成員變數賦值給一個臨時變數,然後使用該臨時變數即可

調整分割槽數的重要性

剛開始執行的時候,預設分割槽數為2,結果在叢集上面執行的時間甚至比本地都慢。通過Web UI檢視任務狀態,如下圖:
這裡寫圖片描述
這裡寫圖片描述
可以看到每個stage只有2個task,4個executor實際上只有兩個參與了運算,並行度真是夠低的。
調整方式:在用textFile函式讀取檔案的時候指定分割槽數,由於叢集中有4個executor,而分割槽數最好是executor數量的整數倍,因此將分割槽數指定為8,調整後,結果如下所示:
這裡寫圖片描述
這裡寫圖片描述
可見4個executor都參與了運算,並行度有了顯著提升。