Spark讀取HDFS文件,任務本地化(NODE_LOCAL)

Spark也有數據本地化的概念(Data Locality),這和MapReduce的Local Task差很少,若是讀取HDFS文件,Spark則會根據數據的存儲位置,分配離數據存儲最近的Executor去執行任務。sql

這麼理解沒錯,我搭建的Spark集羣狀況是這樣:網絡

15臺DataNode節點的HDFS集羣,我在每一個DataNode上都部署了一個Spark Worker,而且,啓動Spark Application的時候,每一個Worker都有一個Executor,這樣理論上來講,只要讀取HDFS文件,Spark均可以使用本地任務來讀取(NODE_LOCAL)。學習

在$SPARK_HOME/conf/slaves文件中配置了每一個Worker的hostname,以後在Master上,執行$SPARK_HOME/sbin/start-slaves.sh來啓動Workers,啓動以後集羣如圖顯示:大數據

須要大數據學習資料和交流學習的同窗能夠加大數據學習羣:724693112 有免費資料分享和一羣學習大數據的小夥伴一塊兒努力spa


 

進入spark-sql,從hive中掃描一張表,執行狀況以下:blog

 


 

奇怪的是,全部讀取HDFS文件的Task Locality Level所有是ANY,也就是說,沒有一個使用NODE_LOCAL本地化任務,這樣致使集羣的網絡消耗很是大(由於全部的數據都要經網絡拷貝一遍),如圖,後面那個峯值是執行任務的網絡狀況:部署

 


 

直接說緣由和解決辦法吧。it

請注意最上面集羣狀況的圖中,Worker Id和Address中都使用的IP地址做爲Worker的標識,而HDFS集羣中通常都以hostname做爲slave的標識,這樣,Spark從HDFS中獲取文件的保存位置對應的是hostname,而Spark本身的Worker標識爲IP地址,二者不一樣,所以沒有將任務的Locality Level標記爲NODE_LOCAL,而是ANY。奇怪的是,我在Spark的slaves文件中都配置的是hostname,爲什麼集羣啓動後都採用了IP地址?最大的多是/etc/hosts文件的配置。spark

大數據學習交流羣:724693112 歡迎想學習大數據和須要大數據學習資料的同窗來一塊兒學習。io

解決辦法是:沒有采用slaves文件+start-slaves.sh的方式啓動,而是每臺Worker單獨啓動,

使用命令:$SPARK_HOME/sbin/start-slave.sh -h ,這樣啓動以後,Spark WEBUI中Worker Id和Address中都以hostname來顯示了,如圖:

 


 

再次進入spark-sql,執行一樣的任務,全部的Task Locality Level都是NODE_LOCAL,沒有網絡傳輸,速度比以前快了好幾倍。


 

這纔是指望的結果,至於致使salves文件中配置的明明是hostname,爲什麼Spark集羣中解析成IP地址的緣由,後續再查吧。

相關文章
相關標籤/搜索