Spark與MapReduce的對比誤區與真正優勢

2021-10-14 02:12:50 字數 3167 閱讀 2555

3.spark相比mapreduce可以減少磁碟io嗎?

spark比mapreduce快在哪?

經常聽到有人說spark基於記憶體計算,將中間結果儲存在記憶體中,避免了磁碟io的次數。我覺得這句話的表面意思都對,但是很多人並沒有了解其真正的含義。

知乎:

什麼是記憶體計算,如果是指把磁碟中的資料讀取到記憶體中做計算的話,那麼mapreduce肯定也是記憶體計算。spark的特殊之處在於可以將rdd快取到記憶體之中,下次再使用此rdd時,不用再次計算,而是直接從記憶體中獲取。

什麼是中間結果?如果中間結果的含義不表達清楚,這個問題是沒有意義的。而且必須要明白spark的執行原理。

spark rdd的執行邏輯

我們知道spark可以將多個運算元連線在一起,以「流水線」的方式進行計算。為什麼要把流水線加上引號?因為我的理解,流水線處理應該是多個處理步驟連線,每個處理步驟接收上乙個處理步驟的結果進行計算,然後再將處理結果輸送給下乙個處理步驟。並且每個處理步驟不斷迴圈接收-處理-傳送步驟,結束當前迴圈後,立即進行下一迴圈。那麼spark的處理是否為流水線處理呢?

spark會將dag劃分為stage,乙個stage中包含不需要shuffle操作的rdd。那麼連線的rdd是怎麼執行計算任務的呢?每乙個rdd都有乙個compute函式,返回值為迭代器型別,函式內容一般為:獲取上乙個rdd compute函式生成的迭代器,構造本rdd生成的迭代器,在迭代器的next函式中,新增本rdd的處理邏輯。這也是為什麼spark rdd是惰性計算,因為每次連線的運算元只是將計算邏輯新增在了 compute函式所構造的迭代器中,並沒有實際計算。

所以說rdd計算並不是乙個真正的流水線過程,它更像是多層巢狀的函式。由於多層巢狀,每一層都要呼叫下層的函式獲取結果,再進行本層的處理邏輯。那能不能把多層巢狀函式,直接變成乙個函式呢?spark的鎢絲計算中的全階段**生成就是將多個連線的運算元直接變成乙個運算元,避免了多層級的迭代器next函式的呼叫,減少了虛函式的呼叫的消耗,提高了計算效率。

所以spark將中間結果儲存在記憶體中嗎?

但要明白,只有快取rdd可以使spark的處理效率顯著高於mapreduce,spark和mapreduce都是在記憶體中計算資料的,shuffle都需要寫入磁碟。

spark和mapreduce的shuffle過程都是需要磁碟io的,但是為什麼總說spark可以減少磁碟io呢?這是因為dag計算模型與mapreduce計算模型的區別。

mapreduce計算模型只包括map和reduce兩個階段,兩個節點使用shuffle連線,那麼如果在reduce階段資料還需要再一次shuffle,那應該怎麼辦呢?就只能結束當前job,將資料寫入磁碟。然後再啟動乙個job讀取資料進行操作。那spark有何嘗不是呢?只要需要shuffle,一定會寫入磁碟。區別在**?

兩個mapreduce job的連線:

map -> 磁碟io -> reduce -> 磁碟io -> map -> 磁碟io ->reduce。

spark多個stage連線:

stage -> 磁碟io -> stage -> 磁碟io -> stage -> 磁碟io ->stage

為什麼第乙個reduce和第二個map之間的要進行磁碟io?如果第二個map的計算邏輯可以直接合併到第乙個reduce中,那麼是完全不需要將第乙個reduce的結果寫入磁碟中的。再開啟乙個mapreduce job的原因一定是因為第乙個reduce和第二個map之間需要資料shuffle。

那這跟spark的stage連線有什麼區別?每個stage之間都需要資料shuffle。這看起來似乎是相同的,其實本質上就是相同的。mapreduce 兩個job之間的連線完全可以通過編寫第乙個reduce和第二個map的處理邏輯,使得第乙個reduce和第二個map之間變成乙個shuffle。那麼這樣其實就和spark的計算邏輯是相同的。

但是沒有人會這樣做,因為實現shuffle的邏輯太複雜了,所以使用者一般都是先用第二個map讀取磁碟檔案,然後利用mapreduce的shuffle過程去進行shuffle。這就造成了多了一次磁碟io,究其原因是因為一次mapreduce job只能進行一次shuffle。這在spark中是沒必要的,因為spark dag計算邏輯自然的包括了多個shuffle過程,不需要重新啟動新的spark job去進行操作。

所以綜上來看,這是dag模式和mapreduce模型的區別。mapreduce模型的侷限性導致其必須進行更多的磁碟io。通過設計第乙個reduce和第二個map的邏輯將其變成shuffle,減少磁碟io?這不是就spark dag嗎,別人已經幫你做好了。

spark基於記憶體計算,將中間結果儲存在記憶體中,避免了磁碟io的次數。這句話沒錯,但這是spark比mapreduce快的原因嗎?從上面的分析中我們可以看出,並不準確,也不完全。

spark真的比mapreduce快的地方在於:

快取rdd

中間計算的rdd結果快取在記憶體中,當再次使用時,直接從記憶體中獲取,而不是再次計算或從磁碟中獲取。所以spark適合迭代式的計算。

dag計算模型

dag計算模型可以實現單個job多次shuffle,而mapreduce一次job只能進行一次shuffle,所以對於需要多次shuffle的計算場景,spark的磁碟io次數少於mapreduce。

spark shuffle優化

mapreduce在shuffle時預設進行排序。spark在shuffle時則只有部分場景才需要排序。排序是非常耗時的。

多執行緒模型

mapreduce採用了多程序模型,而spark採用了多執行緒模型。多程序模型的好處是便於細粒度控制每個任務占用的資源,但每次任務的啟動都會消耗一定的啟動時間。spark則是通過復用執行緒池中的執行緒來減少啟動、關閉task所需要的開銷。多執行緒模型也有缺點,由於同節點上所有任務執行在乙個程序中,因此,會出現嚴重的資源爭用,難以細粒度控制每個任務占用資源(借鑑別人的)。

鎢絲計畫

spark 鎢絲計畫中優化了對記憶體的使用,可以直接操作二進位制資料,減少了gc,避免oom。設計了快取友好的演算法,以及**生成技術。

其實用第五點說明是不合適的,這是在spark發展成熟之後的優化措施。spark與mapreduce的本質差別還是在1、2、3點。

以上均為本人自己的理解,如果有錯誤請指出!

Spark與MapReduce的區別

spark中最核心的概念是rdd 彈性分布式資料集 近年來,隨著資料量的不斷增長,分布式集群平行計算 如mapreduce dryad等 被廣泛運用於處理日益增長的資料。這些設計優秀的計算模型大都具有容錯性好 可擴充套件性強 負載平衡 程式設計方法簡單等優點,從而使得它們受到眾多企業的青睞,被大多數...

MapReduce與Spark的異同

spark是借鑑了mapreduce並在其基礎之上發展起來的,繼承了分布式計算的優點並改進了mapreduce的劣勢 1.spark把運算的中間資料存放在記憶體,迭代計算效率更高,spark中除了基於記憶體計算外,還有執行任務的dag有向無環圖 mapreduce的中間結果需要儲存到磁碟,這樣必然會...

Spark與MapReduce的區別是什麼?

spark和mapreduce都是可以處理海量資料,但是在處理方式和處理速度上存在著差異,總結如下 1.spark處理資料是基於記憶體的,而mapreduce是基於磁碟處理資料的。mapreduce是將中間結果儲存到磁碟中,減少了記憶體占用,犧牲了計算效能。spark是將計算的中間結果儲存到記憶體中...