Apache Spark技術實戰之6 -- spark-submit常見問題及其解決


除本人同意外,嚴禁一切轉載,徽滬一郎。

概要

編寫了獨立運行的Spark Application之后,需要將其提交到Spark Cluster中運行,一般會采用spark-submit來進行應用的提交,在使用spark-submit的過程中,有哪些事情需要注意的呢?

本文試就此做一個小小的總結。

spark-defaults.conf

Spark-defaults.conf的作用范圍要搞清楚,編輯driver所在機器上的spark-defaults.conf,該文件會影響 到driver所提交運行的application,及專門為該application提供計算資源的executor的啟動參數

只需要在driver所在的機器上編輯該文件,不需要在worker或master所運行的機器上編輯該文件

舉個實際的例子

spark.executor.extraJavaOptions	   -XX:MaxPermSize=896m
spark.executor.memory		   5g
spark.serializer        org.apache.spark.serializer.KryoSerializer
spark.cores.max		32
spark.shuffle.manager	SORT
spark.driver.memory	2g

 上述配置表示為該application提供計算資源的executor啟動時, heap memory需要有5g。

這里需要引起注意的是,如果worker在加入cluster的時候,申明自己所在的機器只有4g內存,那么為上述的application分配executor是,該worker不能提供任何資源,因為4g<5g,無法滿足最低的資源需求。

spark-env.sh

spark-env.sh中最主要的是指定ip地址,如果運行的是master,就需要指定SPARK_MASTER_IP,如果准備運行driver或worker就需要指定SPARK_LOCAL_IP,要和本機的IP地址一致,否則啟動不了。

配置舉例如下

export SPARK_MASTER_IP=127.0.0.1
export SPARK_LOCAL_IP=127.0.0.1

啟動spark集群

第一步啟動master

$SPARK_HOME/sbin/start-master.sh

第二步啟動worker

$SPARK_HOME/bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077

將master替換成MASTER實際運行的ip地址

如果想在一台機器上運行多個worker(主要是用於測試目的),那么在啟動第二個及后面的worker時需要指定—webui-port的內容,否則會報端口已經被占用的錯誤,啟動第二個用的是8083,第三個就用8084,依此類推。

$SPARK_HOME/bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
    –webui-port 8083

 這種啟動worker的方式只是為了測試是啟動方便,正規的方式是用SPARK_HOME/sbin/start-slaves.sh來啟動多個worker,由於涉及到ssh的配置,比較麻煩,我這是圖簡單的辦法。

用$SPARK\_HOME/sbin/start-slave.sh$來啟動worker時有一個默認的前提,即在每台機器上$SPARK_HOME必須在同一個目錄。

使用相同的用戶名和用戶組來啟動Master和Worker,否則Executor在啟動后會報連接無法建立的錯誤。

我在實際的使用當中,遇到”no route to host”的錯誤信息,起初還是認為網絡沒有配置好,后來網絡原因排查之后,忽然意識到有可能使用了不同的用戶名和用戶組,使用相同的用戶名/用戶組之后,問題消失。

spark-submit

spark集群運行正常之后,接下來的問題就是提交application到集群運行了。

Spark-submit用於Spark application的提交和運行,在使用這個指令的時候最大的困惑就是如何指定應用所需要的依賴包。

首先查看一下spark-submit的幫助文件

$SPARK_HOME/bin/submit --help

有幾個選項可以用來指定所依賴的庫,分別為

  • --driver-class-path driver所依賴的包,多個包之間用冒號(:)分割
  • --jars   driver和executor都需要的包,多個包之間用逗號(,)分割

為了簡單起見,就通過—jars來指定依賴,運行指令如下

$SPARK_HOME/bin/spark-submit –class 應用程序的類名 \
--master spark://master:7077 \
--jars 依賴的庫文件 \
spark應用程序的jar包

需要提醒的時,這些上傳到worker的文件,需要定時做手工清理,否則會占用許多磁盤空間

問題1

由於Spark在計算的時候會將中間結果存儲到/tmp目錄,而目前linux又都支持tmpfs,其實說白了就是將/tmp目錄掛載到內存當中。

那么這里就存在一個問題,中間結果過多導致/tmp目錄寫滿而出現如下錯誤

No Space Left on the device

解決辦法就是針對tmp目錄不啟用tmpfs,修改/etc/fstab

問題2

有時可能會遇到java.lang.OutOfMemory, unable to create new native thread的錯誤,導致這種錯誤的原因比較多。

有一種情況並非真的是內存不足引起的,而是由於超出了允許的最大文件句柄數或最大進程數。

排查的步驟就是查看一下允許打開的文件句柄數和最大進程數,如果數值過低,使用ulimit將其調高之后,再試試問題是否已經解決。

ulimit -a

修改允許打開的最大進程數

ulimit -u 65535

修改允許打開的文件句柄

ulimit -n 65535

spark-shell

上面講述了spark-submit提交Spark Application如何解決依賴庫的問題,那如果是spark-shell的話,該怎么辦呢?

spark-shell的話,利用--driver-class-path選項來指定所依賴的jar文件,注意的是--driver-class-path后如果需要跟着多個jar文件的話,jar文件之間使用冒號(:)來分割。

小結

本文部分內容已由本人徽滬一郎在CSDN中通過”使用Spark+Cassandra打造高性能數據分析平台“發表。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM