【前言:筆者將分兩篇文章進行闡述Spark和MapReduce的對比,首篇側重於"宏觀"上的對比,更多的是筆者總結的針對"相對於MapReduce我們為什麼選擇Spark"之類的問題的幾個核心歸納點;次篇則從任務處理級別運用的並行機制方面上對比,更多的是讓大家對Spark為什麼比MapReduce快有一個更深、更全面的認識。通過兩篇文章的解讀,希望幫助大家對Spark和MapReduce有一個更深入的瞭解,並且能夠在遇到諸如"MapReduce相對於Spark的侷限性?"等類似的面試題時能夠得到較好地表現,順利拿下offer】
首先糾正一個誤區:在瀏覽Spark官網時,經常能看到如下這張圖:
從上圖可以看出Spark的運行速度明顯比Hadoop(其實是跟MapReduce計算引擎對比)快上百倍!相信很多人在初學Spark時,認為Spark比MapReduce快的第一直觀概念都是由此而來,甚至筆者發現網上有些資料更是直接照搬這個對比,給初學者造成一個很嚴重的誤區。
這張圖是分別使用Spark和Hadoop運行邏輯迴歸機器學習算法的運行時間比較,那麼能代表Spark運行任何類型的任務在相同的條件下都能得到這個對比結果嗎?很顯然是不對的,對於這個對比我們要知其然更要知其所以然。
首先,大多數機器學習算法的核心是什麼?就是對同一份數據在訓練模型時,進行不斷的迭代、調參然後形成一個相對優的模型。而Spark作為一個基於內存迭代式大數據計算引擎很適合這樣的場景,之前的文章《Spark RDD詳解》也有介紹,對於相同的數據集,我們是可以在第一次訪問它之後,將數據集加載到內存,後續的訪問直接從內存中取即可。但是MapReduce由於運行時中間結果必然刷磁盤等因素,導致不適合機器學習等的迭代場景應用,還有就是HDFS本身也有緩存功能,官方的對比極有可能在運行邏輯迴歸時沒有很好配置該緩存功能,否則性能差距也不至於這麼大。
相對於MapReduce,我們為什麼選擇Spark,筆者做了如下總結:
Spark
1.集流批處理、交互式查詢、機器學習及圖計算等於一體
2.基於內存迭代式計算,適合低延遲、迭代運算類型作業
3.可以通過緩存共享rdd、DataFrame,提升效率【尤其是SparkSQL可以將數據以列式的形式存儲於內存中】
4.中間結果支持checkpoint,遇錯可快速恢復
5.支持DAG、map之間以pipeline方式運行,無需刷磁盤
6.多線程模型,每個worker節點運行一個或多個executor服務,每個task作為線程運行在executor中,task間可共享資源
7.Spark編程模型更靈活,支持多種語言如java、scala、python、R,並支持豐富的transformation和action的算子
MapReduce
1.適合離線數據處理,不適合迭代計算、交互式處理、流式處理
2.中間結果需要落地,需要大量的磁盤IO和網絡IO影響性能
3.雖然MapReduce中間結果可以存儲於HDFS,利用HDFS緩存功能,但相對Spark緩存功能較低效
4.多進程模型,任務調度(頻繁申請、釋放資源)和啟動開銷大,不適合低延遲類型作業
5.MR編程不夠靈活,僅支持map和reduce兩種操作。當一個計算邏輯複雜的時候,需要寫多個MR任務運行【並且這些MR任務生成的結果在下一個MR任務使用時需要將數據持久化到磁盤才行,這就不可避免的進行遭遇大量磁盤IO影響效率】
寫在最後
雖然Spark相對於MapReduce有很多優勢,但並不代表Spark目前可以完全取代MapReduce。
筆者之前負責的一個任務,數據存儲格式是parquet,壓縮比比較高,解壓後數據量劇增,又加上存在一些大字段問題,任務比較複雜僅sql語句就幾千行,導致Spark處理時總是報OOM,在有限的資源試了各種調優方法都不能使任務正常穩定的運行。最後改用Hive的原生引擎MapReduce執行,在資源配置相同的情況下,任務能夠穩定運行,而且速度並沒有想象中的那麼慢。所以,對於技術之間的對比以及應用,還是建議首先要對技術本身有深入的理解比如設計思想、編程模型、源碼分析等,並且要結合實際的業務場景需求等,不能空談技術。