天天看點

Apache Spark源碼走讀(三)Spark on Yarn &Spark源碼編譯 &在YARN上運作SparkPi

hadoop2中的yarn是一個分布式計算資源的管理平台,由于其有極好的模型抽象,非常有可能成為分布式計算資源管理的事實标準。其主要職責将是分布式計算叢集的管理,叢集中計算資源的管理與配置設定。

yarn為應用程式開發提供了比較好的實作标準,spark支援yarn部署,本文将就spark如何實作在yarn平台上的部署作比較詳盡的分析。

Apache Spark源碼走讀(三)Spark on Yarn &Spark源碼編譯 &在YARN上運作SparkPi

上圖是spark standalone cluster中計算子產品的簡要示意,從中可以看出整個cluster主要由四種不同的jvm組成:

master 負責管理整個cluster,driver application和worker都需要注冊到master

worker 負責某一個node上計算資源的管理,如啟動相應的executor

executor rdd中每一個stage的具體執行是在executor上完成

driver application driver中的schedulerbackend會因為部署模式的不同而不同

換個角度來說,master對資源的管理是在程序級别,而schedulerbackend則是線上程的級别。

啟動時序圖

Apache Spark源碼走讀(三)Spark on Yarn &Spark源碼編譯 &在YARN上運作SparkPi
Apache Spark源碼走讀(三)Spark on Yarn &Spark源碼編譯 &在YARN上運作SparkPi

yarn的基本架構如上圖所示,由三大功能子產品組成,分别是1) rm (resourcemanager) 2) nm (node manager) 3) am(application master)。

使用者通過client向resourcemanager送出application, resourcemanager根據使用者請求配置設定合适的container,然後在指定的nodemanager上運作container以啟動applicationmaster

applicationmaster啟動完成後,向resourcemanager注冊自己

對于使用者的task,applicationmaster需要首先跟resourcemanager進行協商以擷取運作使用者task所需要的container,在擷取成功後,applicationmaster将任務發送給指定的nodemanager

nodemanager啟動相應的container,并運作使用者task

上述說了一大堆,說白了在編寫yarn application時,主要是實作client和applicatonmaster。執行個體請參考github上的simple-yarn-app.

結合spark standalone的部署模式和yarn程式設計模型的要求,做了一張表來顯示spark standalone和spark on yarn的對比。

standalone

yarn

notes 

client

standalone請參考spark.deploy目錄

master

applicationmaster

worker

executorrunnable

scheduler

yarnclusterscheduler

schedulerbackend

yarnclusterschedulerbackend

作上述表格的目的就是要搞清楚為什麼需要做這些更改,與之前standalone模式間的對應關系是什麼。代碼走讀時,分析的重點是applicationmaster, yarnclusterschedulerbackend和yarnclusterscheduler

Apache Spark源碼走讀(三)Spark on Yarn &Spark源碼編譯 &在YARN上運作SparkPi

一般來說,在client中會顯示的指定啟動applicationmaster的類名,如下面的代碼所示

但在yarn.client中并沒有直接指定applicationmaster的類名,是通過clientarguments進行了封裝,真正指定啟動類的名稱的地方在clientarguments中。構造函數中指定了amclass的預設值是org.apache.spark.deploy.yarn.applicationmaster

将sparkpi部署到yarn上,下述是具體指令。

從輸出的日志可以看出, client在送出的時候,am指定的是org.apache.spark.deploy.yarn.applicationmaster

spark在送出時,所做的資源申請是一次性完成的,也就是說對某一個具體的application,它所需要的executor個數是一開始就是計算好,整個cluster如果此時能夠滿足需求則送出,否則進行等待。而且如果有新的結點加入整個cluster,已經運作着的程式并不能使用這些新的資源。缺少rebalance的機制,這點上storm倒是有。

《hadoop技術内幕 深入解析yarn架構設計與實作原理》 董西成著

本來源碼編譯沒有什麼可說的,對于java項目來說,隻要會點maven或ant的簡單指令,依葫蘆畫瓢,一下子就ok了。但到了spark上面,事情似乎不這麼簡單,按照spark officical document上的來做,總會出現這樣或那樣的編譯錯誤,讓人懊惱不已。

今天閑來無事,又重試了一把,居然o了,做個記錄,以備後用。

我的編譯機器上安裝的linux是archlinux,并安裝後如下軟體

scala 2.11

maven

git

第一步當然是将github上的源碼下載下傳下來

不是直接用maven也不是直接用sbt,而是使用spark中自帶的編譯腳本make-distribution.sh

如果一切順利,會在$spark_home/assembly/target/scala-2.10目錄下生成目标檔案,比如

之前使用sbt編譯一直會失敗的主要原因就在于有些jar檔案因為gfw的原因而通路不了。解決之道當然是添加代理才行。

代理的添加有下面幾種方式,具體哪種好用,一一嘗試吧,對于最新的spark。使用如下指令即可。

方法二,設定java_opts

既然能夠順利的編譯出jar檔案,那麼肯定也改動兩行代碼來試試效果,如果知道自己的發動生效沒有呢,運作測試用例是最好的辦法了。

假設已經修改了$spark_home/core下的某些源碼,重新編譯的話,使用如下指令

假設目前在$spark_home/core目錄下,想要運作一下randomsamplersuite這個測試用例集合,使用以下指令即可。

“spark已經比較頭痛了,還要将其運作在yarn上,yarn是什麼,我一點概念都沒有哎,再怎麼辦啊。不要跟我講什麼原理了,能不能直接告訴我怎麼将spark在yarn上面跑起來,i'm a dummy, just told me how to do it.” 

如果你和我一樣是一個對形而上的東西不是太感興趣,而隻糾結于怎麼去做的話,看這份guide保證不會讓你失望, :)。

本文所有的操作基于arch linux,保證下述軟體已經安裝

jdk

scala

hadoop像它的logo一樣,真得是一個體形無比巨大的大象,如果直接入手去搞這個東東的話,肯定會昏上好長一段時間。個人取巧,從storm弄起,一路走來還算平滑。

hadoop最主要的是hdfs和mapreduce framework,針對第二代的hadoop即hadoop 2這個framework變成了非常流行的yarn, 要是沒聽說過yarn,都不好意思說自己玩過hadoop了。

不開玩笑了,注意上面一段話中最主要的資訊就是hdfs和mapreduce framework,我們接下來的所有配置都是圍繞這兩個主題來的。

添加使用者組: hadoop,  添加使用者hduser

假設目前是以root使用者登入,現在要切換成使用者hduser

下載下傳hadoop 2.4并解壓

為了避免每次都要重複設定這些變量,可以将上述語句加入到.bashrc檔案中。

接下來建立的目錄是為hadoop中hdfs相關的namenode即datanode使用

下列檔案需要相應的配置

yarn-site.xml

core-site.xml

hdfs-site.xml

mapred-site.xml

切換到hadoop安裝目錄

修改etc/hadoop/yarn-site.xml, 在<configuration>和</configuration>之間添加如下内容,其它檔案添加位置與此一緻:

etc/hadoop/core-site.xml

etc/hadoop/hdfs-site.xml

etc/hadoop/mapred-site.xml

驗證一下hadoop搭建成功與否的最好辦法就是在上面跑個wordcount試試

将檔案複制到hdfs中

運作wordcount

檢視運作結果

先歇一會,配置到這裡,已經一頭汗了,接下來将spark在yarn上的運作,再堅持一小會

下載下傳spark for hadoop2的版本

繼續以hduser身份運作,最主要的一點就是設定yarn_conf_dir或hadoop_conf_dir環境變量

運作結果儲存在相關application的stdout目錄,使用以下指令可以找到

假設找到的檔案為./logs/userlogs/application_1400479924971_0002/container_1400479924971_0002_01_000001/stdout,使用cat可以看到結果

繼續閱讀