《Spark 官方文檔》在Mesos上運行Spark
在Mesos上運行Spark
Spark可以在由Apache Mesos 管理的硬件集群中運行。
在Mesos集群中使用Spark的主要優勢有:
- 可以在Spark以及其他框架(frameworks)之間動態劃分資源。
- 可以同時部署多個Spark實例,且各個實例間的資源分配可以調整。
工作原理
在獨立部署的Spark集群中,下圖裏的Cluster Manager代表Spark master。然而,在Mesos集群中,Mesos master將取代Spark master在下圖中的地位。
如果一個Spark驅動程序(driver)提交一個作業(job)並開始分發調度作業相關的任務(task),將會由Mesos來決定每個任務分發到哪台機器上。Mesos在調度短期任務的時候,會根據提交任務的賬號來動態分配資源,而不需要依賴於靜態的資源劃分。
按以下所示的步驟,來安裝Mesos,以及向Mesos提交Spark作業。
安裝Mesos
Spark 1.6.0使用Mesos 0.21.0的時候,不需要任何特殊的Mesos補丁包。
如果你已經有一個Mesos集群,可以忽略Mesos安裝這一步。
為Spark安裝的Mesos和你為其他框架安裝的Mesos沒有什麼不同。既可以從源代碼安裝,也可以從預編譯好的包安裝。
使用源代碼安裝
按以下步驟可以使用源代碼安裝Apache Mesos:
- 從鏡像(mirror)下載一個Mesos發布版本
- 按Mesos的開始頁(Getting Started)所示的步驟來編譯和安裝Mesos
注意:如果你不想把Mesos安裝到係統默認路徑下(比如,你沒有管理員權限),可以通過configure腳本的–prefix參數來指定安裝路徑,例如,configure –prefix=/home/me/mesos。默認的安裝路徑是/usr/local。
使用第三方包安裝
Apache Mesos項目本身隻發布源碼包,但你可以從一些第三方項目中找到Mesos的二進製發布包,二進製包在安裝時相對更方便一些。
其中一個第三方項目是Mesosphere。按以下步驟可以安裝Mesosphere提供的二進製發布包:
- 從下載頁麵(downloads page)下載Mesos安裝包
- 按頁麵上所提供的安裝指令即可安裝和配置Mesos
Mesosphere的安裝文檔中建議使用Zookeeper來設置Mesos master的容錯備份,但其實Mesos並不依賴於Zookeeper,可以以單master方式運行。
驗證
接下來,需要通過瀏覽Mesos master的Web UI(其端口為5050)來確認一下,是否頁麵上slave tab顯示了所有集群中的slave機器。
Spark連接Mesos
要在Mesos上運行Spark,你需要在Mesos能訪問到的地方部署Spark的二進製包,並且需要配置一下Spark驅動程序(driver)以便使其可以連接到Mesos。
當然,你也可以把Spark安裝到Mesos slave機器上和Mesos相同的目錄下,然後配置一下spark.mesos.executor.home(默認等於${SPAKR_HOME}),使其指向這個目錄。
上傳Spark包
Mesos在某個slave機器上首次運行Spark任務的時候,slave機器上需要一個運行Spark Mesos executor backend的二進製包,這個Spark包可以放在任何能夠以Hadoop兼容URL訪問到的地方,包括HTTP( https://
, Amazon Simple Storage Service)、s3n(s3n://)、
HDFS (hdfs://
)
要使用預編譯好的二進製包:
- 從這裏(download page)下載Spark二進製包
- 將Spark二進製包上傳到可訪問的的存儲:hdfs/http/s3
要存到HDFS上,可以使用Hadoop fs put 命令:hadoop fs -put spark-1.6.0.tar.gz /path/to/spark-1.6.0.tar.gz
或者,你也可以編譯一個自定義Spark版本,可以使用Spark源碼中tarball/checkout下的 make-distribution.sh腳本來打包:
- 下載並編譯Spark(參考這裏here)
- 創建一個二進製包:make-distribution.sh –tgz
- 將Spark二進製包上傳到可訪問的存儲:hdfs/http/s3
Mesos Master URL
Mesos Master URL有兩種形式:
- 單master為 mesos://host:5050
- 基於Zookeeper的多master為 mesos://zk://host:2181
客戶端模式
客戶端模式下,客戶端機器上將會啟動一個Spark Mesos框架,並且會等待驅動(driver)的輸出。
驅動需要spark-env.sh中的一些配置項,以便和Mesos交互操作:
- 在Spark-env.sh中設置一些環境變量:
- export MESOS_NATIVE_JAVA_LIBRARY=<path to libmesos.so>。一般情況下,這個路徑是 <prefix>/lib/libmesos.so,其中prefix的默認值是/usr/local。見前麵的Mesos安裝所述。在Mac OS X係統中,libmesos.so的名字變為libmesos.dylib。
- export SPARK_EXECUTOR_URI=<上文所述的上傳spark-1.6.0.tar.gz對應的URL>
- 同樣,spark.executor.uri 也需要設成<上文所述的上傳spark-1.6.0.tar.gz對應的URL>
然後,你就可以向這個Mesos集群提交Spark應用了,當然,你需要把Mesos Master URL(mesos:// )傳給SparkContext,例如:
val conf = new SparkConf()
.setMaster("mesos://HOST:5050")
.setAppName("My app")
.set("spark.executor.uri", "<path to spark-1.6.0.tar.gz uploaded above>");
val sc =newSparkContext(conf);
(你也可以在conf/spark-defaults.conf文件中配置spark.executor.uri,然後通過 spark-submit
腳本來提交Spark應用)
如果是在Spark shell中,spark.executor.uri參數值是從SPARK_EXECUTOR_URI繼承而來的,所以不需要額外再傳一個係統屬性。
./bin/spark-shell --master mesos://host:5050
集群模式
Mesos同樣也支持Spark以集群模式提交作業,這種模式下,驅動器將在集群中某一台機器上啟動,其運行結果可以在Mesos Web UI上看到。
要使用集群模式,你首先需要利用 sbin/start-mesos-dispatcher.sh腳本啟動 MesosClusterDispatcher,並且將Mesos Master URL(如:mesos://host:5050)傳給該腳本。MesosClusterDispatcher啟動後會以後台服務的形式運行在本機。
如果你想以Marathon框架運行MesosClusterDispatcher,那麼就需要在前台運行MesosClusterDispatcher(如:bin/spark-class org.apache.spark.deploy.mesos.MesosClusterDispatcher)
客戶機現在可以向Mesos集群提交任務了,如下示例,你可以用spark-submit腳本,並將master URL指定為MesosClusterDispatcher的URL(如:mesos://dispatcher:7077)。然後,你可以在Spark集群Web UI上查看驅動器程序的狀態。
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master mesos://207.184.161.138:7077 \
--deploy-mode cluster \
--supervise \
--executor-memory 20G \
--total-executor-cores 100\
https://path/to/examples.jar \
1000
注意,spark-submit中所涉及的jar包或python文件必須傳到Mesos可以以URI形式訪問到的位置,Spark驅動是不會自動上傳任何本地jar包或python文件的。
Mesos運行模式
Spark可以在Mesos的兩種模式下運行:“粗粒度”模式(默認)和“細粒度”模式。
“粗粒度”模式下,Mesos在每台機器上隻啟動一個長期運行的Spark任務,而Spark任務則會作為其內部的“mini-tasks”來動態調度。這樣做的好處是,啟動延遲會比較低,但同時,也會增加一定的資源消耗,因為Mesos需要在整個生命周期內為這些長期運行的Spark任務保留其所需的資源。
粗粒度是Mesos的默認模式。你也可以顯示地在 SparkConf 中設置spark.mesos.coarse屬性為true來啟用該模式:
conf.set("spark.mesos.coarse","true")
另外,在粗粒度模式下,你可以控製Spark所使用資源的上限。默認情況下,Spark會申請集群中所有的CPU(當然是Mesos所能提供的),這其實並不合理,除非你每次隻啟動一個應用。你可以通過SparkConf設置個帽子(上限),如:conf.set(“spark.cores.max”, “10)
在細粒度模式下,每個Spark任務都作為獨立的Mesos任務運行。這使得多個Spark實例(或者其他計算框架)可以比較細粒度地共享機器資源,每個應用所獲得的機器資源也會隨著應用的啟動和關閉而增加或減少,但同時每個任務的啟動也會有相應的延遲。這種模式可能不適用於一些低延遲的場景,如:交互式查詢,響應web請求等。
要使用細粒度模式,可以在SparkConf 中將 spark.mesos.coarse 屬性設為false:
conf.set("spark.mesos.coarse","false")
你還可以用spark.mesos.constraints屬性來設置mesos資源分配約束條件。默認是沒有約束的,也就是所有的資源分配都是可接受的。
conf.set("spark.mesos.constraints","tachyon:true;us-east-1:false")
例如,我們把spark.mesos.constraints設為tachyon:true;us-east-1:false,接下來,資源分配將會檢查新分配的資源(機器)是否符合這兩項約束,隻有符合約束的機器才會啟動新的Spark執行器(executor)。
Mesos對Docker的支持
Spark可以使用Mesos Docker集裝箱,你需要在 SparkConf 中設置spark.mesos.executor.docker.image屬性。
所使用的Docker鏡像必須已經包含特定的Spark版本,或者也可以使用Mesos的慣用方法下載Spark。
支持Docker需要Mesos 0.20.1及以上版本。
和Hadoop一起運行
你可以將Spark和Mesos作為機器上獨立服務,和已有的Hadoop集群部署在一起。要從Spark訪問Hadoop數據,需要一個完整的hdfs:// URL(通常是 hdfs://<namenode>:9000/path,你可以在Hadoop Namenode Web UI上看到這個URL)。
另外,你也可以在Mesos上運行Hadoop MapReduce,以便達到Mesos和Hadoop之間更好的資源隔離和共享。這種場景下,Mesos就是一個全局唯一的調度器,同時為Hadoop和Spark分配CPU,而不再是利用Linux調度器來共享CPU資源。更詳細的請參考Hadoop on Mesos。
但是不管是上麵哪種場景,HDFS始終是獨立於Hadoop MapReduce的,也不需要Mesos的調度。
Mesos中的動態資源分配
Mesos在粗粒度模式下,可以支持動態分配,Mesos會基於應用的統計信息調整執行器(executor)的個數。粗粒度模式下,由於Mesos被設計成在每個slave上隻啟動一個執行器,所以Mesos的粗粒度調度器本身隻支持減少資源分配,而動態分配同時支持減少和增加執行器的個數。所以在粗粒度調度器減少執行器個數後,如果Spark表示需要更多執行器的時候,Mesos又會重新把執行器個數提升為原值。
由於Mesos目前還不支持對其他框架作業終止的通知,所以想要使用動態分配這個特性的用戶,需要開啟Mesos Shuffle Service,來清理shuffle產生的臨時數據。可以使用sbin/start-mesos-shuffle-service.sh 和 sbin/stop-mesos-shuffle-service.sh 來啟動和停止Mesos Shuffle Service。
Shuffle Service需要在每個運行Spark執行器(executor)的節點上啟動。最簡單的實現方式就是在Mesos上使用Marathon啟動Shuffle Service,並添加一個主機唯一的限製。
配置
Spark更詳細的配置可參考這裏:configuration page 。以下為Spark on Mesos的相應配置:
Spark Properties(Spark屬性)
屬性名 | 默認值 | 含義 |
---|---|---|
spark.mesos.coarse |
false | 如果設為true,則運行於Mesos集群粗粒度模式下(“coarse-grained” sharing mode),這種模式下,Spark需要運行一個長期Mesos任務。這樣可以有效減少小型查詢的延遲,但同時也會增加整個Spark作業生命周期內對集群資源的占用。 |
spark.mesos.extra.cores |
0 |
每一個task的額外CPU資源請求。僅在粗粒度模式下生效。每個task所申請的CPU個數 = 集群提供的個數 + 該配置所設定的個數。注意,執行器鎖申請的總CPU個數不會超過 spark.cores.max |
spark.mesos.mesosExecutor.cores |
1.0 |
每個Mesos執行器的CPU個數(僅細粒度模式有效)。這不包括用於執行Spark tasks的CPU。換句話說,即使沒有任何Spark任務在運行,每個Mesos執行器也會占用這麼多個CPU。注意,該值可以是一個浮點數。 |
spark.mesos.executor.docker.image |
(none) | 容納Spark執行器的docker鏡像名稱。這個鏡像中必須包含Spark以及兼容的Mesos庫。鏡像中的Spark安裝路徑可以由spark.mesos.executor.home指定;Mesos庫的安裝路徑可以由 spark.executor.Env.MESOS_NATIVE_JAVA_LIBRARY指定。 |
spark.mesos.executor.docker.volumes |
(none) | 設置掛載到docker鏡像中的卷標(docker鏡像由spark.mesos.executor.docker.image設置)。該屬性值為逗號分隔的卷標路徑映射列表,其格式同docker run -v所需參數,如下:
[host_path:]container_path[:ro|:rw] |
spark.mesos.executor.docker.portmaps |
(none) | 設置docker鏡像的接入端口映射列表(docker鏡像由spark.mesos.executor.docker.image設置)。格式為逗號分隔的端口映射列表,如下所示:
host_port:container_port[:tcp|:udp] |
spark.mesos.executor.home |
driver side SPARK_HOME
|
設置Mesos執行節點上的Spark安裝目錄。默認情況下,會使用驅動器(driver)所在節點的${SPARK_HOME}路徑。注意,如果設置了spark.executor.uri指定Spark二進製包的位置,那麼本設置將無效。 |
spark.mesos.executor.memoryOverhead |
執行器內存 * 0.10 或384MB中較大者 | 每個執行器(executor)分配的額外內存總量(MB)。其默認值為 384MB或者 spark.executor.memory * 10% 二者中較大者。 |
spark.mesos.uris |
(none) | 驅動器(driver)或執行器(executor)啟動時下載到沙箱中的URI列表。粗粒度和細粒度模式均適用。 |
spark.mesos.principal |
(none) | 設置Spark框架在Mesos集群上的認證身份。 |
spark.mesos.secret |
(none) | 設置Spark框架在Mesos集群上的認證密碼。 |
spark.mesos.role |
* |
設置Spark框架在Mesos集群上的認證角色。角色是Mesos用於保留和分配資源的權重因子。 |
spark.mesos.constraints |
(none) | 基於資源特性的資源分配約束條件。默認,所有分配的資源都是可以接受的。更詳細的資源特性請參考這裏:Mesos Attributes & Resources
|
排錯和調試
調試時需要關注的地方:
-
Mesos master(端口:5050)
- Slave節點應該全部顯示在slaves tab頁上
- Spark應用應該顯示在frameworks tab頁上
- Spark任務應該顯示在framework detail中
- 檢查失敗任務沙箱的標準輸出和標準錯誤
- Mesos日誌
- 默認,master和slave的日誌都保存在/var/log/mesos目錄下
常見陷阱:
- Spark程序集不可訪問
- Slave機器必須能夠通過你指定的https://, hdfs:// 或者 s3n:// 等URL訪問並下載Spark的二進製包
- 防火牆阻斷網絡通信
- 檢查是否有連接失敗消息
- 臨時關閉防火牆以便調試,後續再專門放開幾個端口
- 轉載自 並發編程網 - ifeve.com
最後更新:2017-05-19 17:02:15