1. 程式人生 > >深入分析Spark對MapReduce的底層技術優化

深入分析Spark對MapReduce的底層技術優化

Spark對MapReduce做了大量的改進和優化,主要包括以下個方面:

1)磁碟I/O的讀寫優化:

  • 中間結果快取在記憶體中:隨著實時大資料應用越來越多,Hadoop作為離線的高吞吐、低響應框架已不能滿足這類需求。Hadoop MapReduce的map端將中間輸出和結果儲存在磁碟中,reduce端又需要從磁碟讀寫中間結果,從而造成磁碟I/O成為瓶頸。Spark則允許將map端的中間輸出和結果快取在記憶體中,從而使得reduce端在拉取中間結果時避免了大量的磁碟I/O。
  • 應用程式上傳的資原始檔快取在Driver本地檔案服務的記憶體中:Hadoop YARN中的ApplicationMaster申請到Container後,具體任務需要利用NodeManager從HDFS的不同節點下載任務所需的資源(如Jar包),增加了磁碟I/O。Spark則將應用程式上傳的資原始檔快取在Driver本地檔案服務的記憶體中,當Executor執行任務時直接從Driver的記憶體中讀取,從而節省了大量的磁碟I/O。

2)任務的並行處理優化:由於將中間結果寫到磁碟與從磁碟讀取中間結果屬於不同的環節,Hadoop將它們簡單地通過序列執行銜接起來。而Spark則把不同的環節抽象為Stage,允許多個Stage既可以序列執行,又可以並行執行。

3)任務排程中的資源過濾:當Stage中某個分割槽的Task執行失敗後,會重新對此Stage排程,但在重新排程的時候會過濾已經執行成功的分割槽任務,所以不會造成重複計算和資源浪費。

4)Shuffle排序:Hadoop MapReduce在Shuffle之前會將中間結果按key的hash值和key值大小進行兩層排序,確保分割槽內部的有序性。而Spark則可以根據不同場景選擇在map端排序還是reduce端排序。

5)記憶體管理優化:Spark將記憶體分為堆上的儲存記憶體、堆外的儲存記憶體、堆上的執行記憶體、堆外的執行記憶體4個部分。Spark既提供了執行記憶體和儲存記憶體之間固定邊界的實現,又提供了執行記憶體和儲存記憶體之間“軟”邊界的實現。Spark預設使用“軟”邊界的實現,執行記憶體或儲存記憶體中的任意一方在資源不足時都可以借用另一方的記憶體,最大限度地提高資源的利用率,減少對資源的浪費。Spark由於對記憶體使用的偏好,記憶體資源的多寡和使用率就顯得尤為重要,為此Spark的記憶體管理器提供的Tungsten實現了一種與作業系統的記憶體Page非常相似的資料結構,用於直接操作作業系統記憶體,節省了建立的Java物件在堆中佔用的記憶體,使得Spark對記憶體的使用效率更加接近硬體。Spark會給每個Task分配一個配套的任務記憶體管理器,對Task粒度的記憶體進行管理。Task的記憶體可以被多個內部的消費者消費,任務記憶體管理器對每個消費者進行Task記憶體的分配與管理,因此Spark對記憶體有著更細粒度的管理。