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是將計算的中間結果儲存到記憶體中...