從 MapReduce 的運行機制看它爲何比 Spark 慢

在 Hadoop1 中,MapReduce 計算框架即負責集羣資源的調度,還負責 MapReduce 程序的運行。算法

一,MapReduce 組成

MapReduce 的運行過程有三個關鍵進程:數據庫

1,大數據應用進程。這是用戶啓動的 MapReduce 程序進程,主要是指定 Map 和 Reduce 類、輸入輸出文件路徑等,並提交做業給 Hadoop 集羣的 JobTracker 進程。編程

2,JobTracker 進程。這是 Hadoop 集羣的常駐進程,且全局惟一。主要負責集羣資源分配和任務調度。該進程會根據輸入數據量的大小,命令集羣中每一個 TaskTracker 進程啓動相應數量的 Map 進程和 Reduce 進程。服務器

3,TaskTracker 進程。主要負責啓動和管理 Map 進程或者 Reduce 進程。由於須要每一個數據塊都有對應的 map 函數,因此 TaskTracker 進程一般和 HDFS 中 DataNode 進程啓動在同一個服務器。也就是說 Hadoop 集羣中大多數節點上即運行着 DataNode 進程也運行着 TaskTracker 進程。架構

在 Hadoop1 中 MapReduce 框架即負責集羣的資源調度,還負責 MapReduce 程序的運行。因爲這種架構資源調度和計算高度耦合,致使了一個 Hadoop 集羣中只能跑 MapReduce 計算任務,沒法跑其它的計算任務,維護成本很高。框架

在後面的 Hadoop2 中改爲了 Yarn + MapReduce 架構,將資源的調度工做交給了 Yarn,MapReduce 只負責計算。這樣就能保證 Hadoop 集羣技能跑 MapReduce 計算任務,還能跑任何支持 Yarn 資源調度的計算任務,好比 Spark,Storm 等。分佈式

二,MapReduce 工做流程

上面已經講了 Hadoop1 中 Mapreduce 運行過程當中的三個進程,能夠看出 JobTracker 和 TaskTracker 進程是主從關係,主服務器一般只有一臺,從服務器有不少臺,全部從服務器遵從主服務器的調度。主服務器主要負責整個集羣資源的分配以及 MapReduce 做業的任務調度,從服務器負責執行具體的任務。函數

具體的資源分配,做業調度,具體的做業執行過程,先看下圖:oop

整個過程大概能夠歸納爲:性能

1,用戶啓動大數據應用進程,應用進程 JobClient 將用戶做業 Jar 包存儲到 HDFS 中,未來這些 jar 包會分發給集羣中的服務器執行 MapReduce 計算;

2,應用程序提交做業 job 給 JobTracker;

3,JobTracker 根據做業調度算法建立 JobInprocess 樹,每一個做業都會有一個本身的 JobInprocess 樹;

4,JobInprocess 會根據輸入數據片的數目和設置的 Reduce 數目建立相應數量的 TaskInprocess;

5,JobTracker 進程和 TaskTracker 進程進行定時通訊;

6,若是 TaskTracker 上有空閒的計算資源,JobTracker 會根據該 TaskTracker 節點的資源和須要分配任務的輸入數據塊所在節點的狀況分配相應的 TaskTracker 計算任務;

7,TaskTracker 收到任務後根據任務類型(是 Map 仍是 Reduce)和任務參數 (做業的 jar 包路徑、輸入文件的路徑、要處理的數據在數據庫中的起始偏移量和結束偏移量等),啓動相應的 Map 進程和 Reduce 進程;

8,Map 進程或者 Reduce 進程啓動後,檢查本地是否有執行任務的 jar 包文件,若是沒有就去 HDFS 上去下載,而後加載 Map 或者 Reduce 代碼執行;

9,若是是 Map 進程,就會從 HDFS 讀取數據 (一般狀況下對應的數據就存儲在本機) ,若是是 Reduce 進程就將數據輸出到 HDFS 。

三,Spark 的執行流程

Spark 的運行流程和 MapReduce 一個應用一次只運行一個 map 和一個 reduce 不一樣,Spark 能夠根據應用的複雜程度,分割成更多的階段 (stage) ,這些計算階段組成一個有向無環圖 DAG,Spark 任務調度器能夠根據 DAG 的依賴關係執行計算階段。

所謂的 DAG 就是有向無環圖,就是說不一樣的階段的依賴關係是有向的,計算過程只能沿着依賴關係方向執行,被依賴的階段執行完成以前,依賴的階段不能開始執行,同事依賴關係不能有環型依賴,不然就成爲死循環了。下圖描述了一個典型的 Spark 運行的 DAG 的不一樣階段。

從圖上看,整個應用被切分紅三個階段,階段 3 要依賴階段 1 和階段 2,階段 1 和階段 2 互相不依賴。Spark 在執行調度的時候,先執行階段 1 和階段 2 ,完成之後,再執行階段 3.若是有更多的階段,Spark 的策略也是同樣的。只要根據程序初始化好 DAG,就創建了依賴關係,而後根據依賴關係順序執行各個計算階段,Spark 大數據應用的計算就完成了。

負責 Spark 應用的 DAG 生成和管理的組件是 DAGScheduler,DAGScheduler 根據 RDD 之間的依賴關係生成 DAG,每一個 stage 的劃分依據是 shuffle,每運算到一個涉及到 shuffle 的 RDD 算子就會劃分紅一個 stage。而後會爲每一個 stage 分配必定數量的計算任務。

具體的執行過程以下圖:

大致過程是這樣:

1,Spark 應用程序啓動在本身的 JVM 進程裏,即 Driver 進程,啓動後調用 SparkContext 初始化執行配置和輸入數據。SparkContext 啓動 DAGScheduler 構造執行的 DAG 圖,切分紅最小的執行單位:task;

2,而後 Driver 向 Cluster Manager 請求計算資源,用於 DAG 分佈式計算。Cluster Manager 收到請求後,將 Driver 的主機地址等信息通知給集羣的全部節點 Worker;

3,Worker 收到信息後,根據 Driver 的主機地址,根 Driver 通訊並註冊,而後根據本身的空閒資源領任務,Driver 會根據 DAG 圖開始向註冊的 Worker 分配任務;

4,Worker 收到任務後,啓動 Executor 進程開始執行任務。

四,MapReduce 和 Spark 的異同

其實從本質上講,Spark 能夠算做一種 MapReduce 計算模型的不一樣實現。Hadoop MapReduce 簡單粗暴的根據 shuffle 將大數據計算分紅 Map 和 Reduce 兩個階段,而後就完事了。

而 Spark 相對更加細膩,將前一個的 Reduce 和後一個的 Map 鏈接起來,做爲一個階段持續計算,造成一個更加高效的計算模型,雖然本質依然是 Map 和 Reduce。但這種多個計算階段依賴執行的方案能夠有效的減小對 HDFS 的訪問,減小做業的調度執行次數,所以執行速度更快。

而且和 Hadoop MapReduce 主要使用磁盤存儲 shuffle 過程當中的數據不一樣,Spark 有限使用內存進行數據存儲,包括 RDD 數據。除非內存不夠用了,不然儘量使用內存,這也是 Spark 性能比 Hadoop 高的另外一個緣由。

總結來講,MapReduce 的計算模型更偏向於面向過程編程,Spark 的編程模型更偏向於面向對象編程。Spark 有三個主要特性:RDD 編程模型更簡單DAG 切分的多階段計算過程更快速使用內存存儲中間計算結果更高效。這三個特性使得 Spark 相對 Hadoop MapReduce 能夠有更快的執行速度,以及更簡單的編程實現。

相關文章
相關標籤/搜索