聊聊spark-submit的幾個有用選項


 

我們使用spark-submit時,必然要處理我們自己的配置文件、普通文件、jar包,今天我們不講他們是怎么走的,我們講講他們都去了哪里,這樣我們才能更好的定位問題。

 

我們在使用spark-submit把我們自己的代碼提交到yarn集群運行時,spark會在yarn集群上生成兩個進程角色,一個是driver,一個是executor,當這兩個角色進程需要我們傳遞一些資源和信息時,我們往往會使用spark-submit的選項來進行傳遞。那么這些資源和信息,在使用spark-submit指定了之后,都去了哪里呢,為什么遠在機房的driver和executor能正確的讀到這些東東呢?為什么我明明按照spark-submit的幫助信息指定了這些東西,但是driver或者executor還是報錯呢?本篇文章提供一個方法幫大家進行相關問題的定位。

 

其實spark的driver和executor都是需要把這些資源拉取到其本地才能正常使用的,yarn為driver和executor都提供了container這樣的資源容器來啟動這些進程,但是container也是要和服務器綁定的,那么也就是說雖然driver和executor申請到一定的cpu和內存之后就能啟動,但是他們也會涉及到和持久化存儲打交道,那么我們就需要配置這樣的本地磁盤目錄,通知yarn中啟動的container,如果涉及到文件,可以把這些文件暫存到哪里。這個配置信息在hadoop的core-site.xml中,就是hadoop.tmp.dir:

? ?<property>

? ? ? <name>hadoop.tmp.dir</name>

? ? ? <value>/Users/liyong/software/hadoop/hadoop-2.7.6/tmp</value>

? ? ? <description>A base for other temporary directories.</description>

? ? </property>

我們配置了這個目錄之后,那么在遠程服務器上,啟動了container之后,這個目錄就回作為container綁定的進程的工作目錄了。

為了讓大家能立刻驗證,我們不自己寫代碼,這樣就不需要搭建環境啦打包啦這些亂七八糟的事情了,我們把spark的編譯包下載下來就可以了,而且建議大家先在單機進行驗證,這樣就不用登錄到集群其他節點了。首先來看最簡單的例子:

? ? https://blog.csdn.net/rlnLo2pNEfx9c/article/details/bin/spark-submit \

? ? --class org.apache.spark.examples.SparkPi \

? ? --master yarn \

? ? --num-executors 2 \

? ? examples/target/original-spark-examples_2.11-2.3.0.jar? 100000

當我們把這個任務提交到yarn之后,我們去來觀察一下剛才配置的yarn臨時目錄,這時會生成一個和本次提交的job相關的子目錄:

?https://blog.csdn.net/rlnLo2pNEfx9c/article/details/nm-local-dir/usercache/liyong/appcache/application_1529231285216_0012

其中最后一個application_1529231285216_0012正是我們本次job的applicationId, 進入這個目錄之后,我們可以看到很多子目錄,其中以container開頭的,正是我們提交的job的driver和executor的工作目錄,我們隨便找一個來看看,其中又有很多子目錄和子文件:

640?wx_fmt=png

? ? ?大家可以把這些文件一一打開,和我們的hadoop客戶端的配置文件進行對比一下。還有一個是__spark_conf__.properties文件正是我們的conf/spark-defaults.conf文件,不信你打開對比一下,其實也就是換了個馬甲,大家一定要認識輪家啊。

 

 

英文說明:

? ? Comma-separated list of jars to include on the driver and executor classpaths.

中文解釋:

? ? 需要driver和executor能在其classpath下找到的jar包列表,也就是說,通過這個選項在spark客戶端指定的jar包,會被發送到driver和executor所在節點的classpaths下。我們在進行spark應用開發時,時常會需要還是用到一些spark計算框架本身沒有的依賴jar包,那么我們可以在使用maven或者IDE進行打包時,把需要的依賴都打包到一起,但這並非一種好的方式,因為這樣的話應用包和依賴包耦合性太強,而且依賴比較多的話,我們的打包過程也會很慢,手動把這個包上傳到服務器也會很慢,這就拖慢了我們的整個測試和驗證流程,所以我們可以使用--jars這個選項,來讓spark計算框架幫我們把需要的依賴進行分發。我們來驗證一把:

? ? https://blog.csdn.net/rlnLo2pNEfx9c/article/details/bin/spark-submit \

? ? --class org.apache.spark.examples.SparkPi \

? ? --master yarn \

? ? --num-executors 2 \

? ? --jars /Users/liyong/.m2/repository/org/eclipse/jetty/jetty-plus/9.3.20.? ? v20170531/jetty-plus-9.3.20.v20170531.jar \

? ? examples/target/original-spark-examples_2.11-2.3.0.jar? 100000

在上邊這個命令中,我們通過--jars指定了一個在driver端和executor端需要使用的jar包:jetty-plus-9.3.20.v20170531.jar,我們執行一下,然后去應用所在的目錄查看一下,這時我們發現在每個container的本地目錄下,jetty-plus-9.3.20.v20170531.jar這個包已經安全的躺在那里了,所以下次我們再遇到類找不到的問題,我們就可以去這個目錄下看看,jvm類加載時需要的jar是否在這個目錄下,如果不在,那就肯定會報類找不到的異常了,如果在,那么我們可以使用jar或者unzip命令解壓開這個jar包看看到底有沒有需要的class文件。媽媽再也不用擔心我跑spark時找不到類啦!

英文說明:

? ? Comma-separated list of files to be placed in the working directory of each executor. File paths of these files in executors can be accessed via SparkFiles.get(fileName).

? ? 中文解釋:

這個選項指定的文件會被放置到executor的工作目錄,這樣的話executor就可以通過SparkFiles.get(fileName)這個方法返回這個文件在本地的絕對路徑名,后邊就可以通過各種方式來訪問這個文件了。

? ? 我們在編寫spark應用時,除了需要給spark提供類加載使用的jar包依賴,有時也需要使用一些普通的文件資源,比如我們要做地理位置相關的開發,就需要使用IP地址包這樣的文件;或者我們會使用hive的一些小表(一般是小的維度表)文件,在spark中和這些表的文件進行關聯查詢,那么spark就提供了--files這樣的選項,來幫助我們完成這樣的工作。注意,這里特別說明了,文件會被暫存在executor的工作目錄下,並沒有說被存儲在driver的工作目錄下,但是經過測試發現,driver和executor的工作目錄下都能知道這個文件。我們來驗證一下:

https://blog.csdn.net/rlnLo2pNEfx9c/article/details/bin/spark-submit \

--class org.apache.spark.examples.SparkPi \

--master yarn \

--num-executors 2 \

--jars /Users/liyong/.m2/repository/org/eclipse/jetty/jetty-plus/9.3.20.v20170531/jetty-plus-9.3.20.v20170531.jar \

?--files README.md \

examples/target/original-spark-examples_2.11-2.3.0.jar? 100000

我們這個提交命令中,通過--files選型指定了一個客戶端目錄下的README.md文件,好了我們來執行一下:

640?wx_fmt=png

我們可以看到,本地的三個container(包括driver所在的container)的工作目錄下,都可以找到這個README.md文件了。

英文說明:?

Path to a file from which to load extra properties. If not specified, this will look for conf/spark-defaults.conf.

?中文解釋

通過這個文件指定配置信息,如果沒有指定,spark會使用conf/spark-defaults.conf這個文件作為默認的配置文件。好了,這個說明很明確了,我們只需要來驗證一下即可:

?https://blog.csdn.net/rlnLo2pNEfx9c/article/details/bin/spark-submit \

--class org.apache.spark.examples.SparkPi \

--master yarn \

--num-executors 2 \

--jars /Users/liyong/.m2/repository/org/eclipse/jetty/jetty-plus/9.3.20.v20170531/jetty-plus-9.3.20.v20170531.jar \

?--properties-file conf/myown-spark.conf \

?--files README.md \

examples/target/original-spark-examples_2.11-2.3.0.jar? 100000

我們在spark客戶端的conf目錄下,把spark-default.conf文件拷貝一份,命名為myown-spark.conf,為了和spark-default.conf進行區分,我們在這個我們自己的配置文件中配置3個spark-default.conf里沒有使用的配置項:

? ? ?spark.serializer? org.apache.spark.serializer.KryoSerializer

? ? ?spark.driver.memory? ? ? ? ? ? ? 1g

? ? ?spark.executor.extraJavaOptions? -XX:+PrintGCDetails

提交一下,我們可以在臨時目錄的container的__spark_conf__/目錄下找到__spark_conf__.properties這個文件,文件名還是和之前的一樣,那么我們打開看看,我們自己配置的幾個配置項是否在里邊:

640?wx_fmt=png

看到了吧,標紅色被就是我們自己配置文件中的三個配置項。同時這里大家要注意,要使用spark的配置框架,所有的配置項都需要使用spark作為前綴才行,如果我們不想使用這樣方式,那就需要配合--files選項,把我們自己的配置文件作為普通的資源文件防止到container的工作目錄下,然后使用java或者scala的配置文件sdk去加載了。

 

好了,今天先介紹幾個比較常用的選項,其他的選項大家也可以通過文章里的方式來驗證一下。我們現在知道了spark在進行job提交時,我們配置的資源和依賴都去了哪里,中年女裝品牌那么下來就是要大家去自己探索一下這些資源和依賴都是怎么被發送到各個節點上去的了。

 


更多spark學習和實際項目經驗,請關注spark技術學院,BAT一線工程師為你答疑解惑:

640?wx_fmt=jpeg

 


文章來源:https://blog.csdn.net/rlnLo2pNEfx9c/article/details/80747546


免責聲明!

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



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