從分治算法說起
要說 Hadoop MapReduce 就不得不說分治算法,而分治算法其實說白了,就是四個字 分而治之 。其實就是將一個復雜的問題分解成多組相同或類似的子問題,對這些子問題再分,然后再分。直到最后的子問題可以簡單得求解。
要具體介紹分治算法,那就不得不說一個很經典的排序算法 -- 歸並排序。這里不說它的具體算法代碼,只說明它的主要思想。而歸並排序的思想正是分治思想。
歸並排序采用遞歸的方式,每次都將一個數組分解成更小的兩個數組,再對這兩個數組進行排序,不斷遞歸下去。直到分解成最簡單形式的兩個數組的時候,再將這一個個分解后的數組進行合並。這就是歸並排序。
下面有一個取自百度百科的具體例子可以看看:

我們可以看到,初始的數組是:{10,4,6,3,8,2,5,7}
第一次分解后,變成兩個數組:{10,4,6,3},{8,2,5,7}
分解到最后為 5 個數組:{10},{4,6},{3,8},{2,5},{7}
然后分別合並並排序,最后排序完成:{2,3,4,5,6,7,8,10}
上述的例子這是比較簡單的情況,那么我們想想看,當這個數組很大的時候又該怎么辦呢?比如這個數組達到 100 GB大小,那么在一台機器上肯定是無法實現或是效率較為低下的。
那一台機器不行,那我們可以拆分到多台機器中去嘛。剛好使用分治算法將一個任務可以拆分成多個小任務,並且這多個小任務間不會相互干擾,可以獨立計算。那么我們可以拆分這個數組,將這個數組拆分成 20 個塊,每個的大小為 5 GB。然后將這每個 5 GB的塊分散到各個不同的機器中去運行,最后再將處理的結果返回,讓中央機器再進行一次完整的排序,這樣無疑速度上會提升很多。
上述這個過程就是 Hadoop MapReduce 的大致原理了。
函數式的 MapReduce
Map 和 Reduce 其實是函數式編程中的兩個語義。Map 和循環 for 類似,只不過它有返回值。比如對一個 List 進行 Map 操作,它就會遍歷 List 中的所有元素,然后根據每個元素處理后的結果返回一個新的值。下面這個例子就是利用 map 函數,將 List 中每個元素從 Int 類型 轉換為 String 類型。
val a:List[Int] = List(1,2,3,4)
val b:List[String] = a.map(num => (num.toString))
而 Reduce 在函數式編程的作用則是進行數據歸約。Reduce 方法需要傳入兩個參數,然后會遞歸得對每一個參數執行運算。還是用一個例子來說明:
val list:List[Int] = List(1,2,3,4,5)
//運算順序是:1-2 = -1; -1-3 = -4; -4-4 = -8; -8-5 = -13;
//所以結果等於 -13
list.reduce(_ - _)
談談 Hadoop 的 MapReduce
Hadoop MapReduce 和函數式中的 Map Reduce 還是比較類似的,只是它是一種編程模型。我們來看看 WordCount 的例子就明白了。
在這個 wordcount 程序中,Hadoop MapReduce 會對輸入先進行切分,這一步其實就是分治中分的過程。切分后不同部分就會讓不同的機器去執行 Map 操作。而后便是 Shuffle,這一階段會將不相同的單詞加到一起,最后再進行 Reduce 。
這個 WordCount 程序是官方提供的一個簡易的 Demo,更復雜的任務需要自己分解成 Hadoop MapReduce 模型的代碼然后執行。
所謂 MapReduce 的意思是任何的事情只要都嚴格遵循 Map Shuffle Reduce 三個階段就好。其中Shuffle是系統自己提供的而Map和Reduce則用戶需要寫代碼。
當碰到一個任務的時候,我們需要將它解析成 Map Reduce 的處理方式然后編寫 Hadoop MapReduce 代碼來實現。我看過一個比喻很貼切,Hadoop MapReduce 這個東西這就像是說我們有一把大砍刀,一個錘子。世界上的萬事萬物都可以先砍幾刀再錘幾下,就能搞定。至於刀怎么砍,錘子怎么錘,那就算個人的手藝了。
從模型的角度來看,Hadoop MapReduce 是比較粗糙的,無論什么方法都只能用 Map Reduce 的方式來運行,而這種方式無疑不是萬能的,很多應用場景都很難解決。而從做數據庫的角度來看,這無非也就是一個 select + groupBy() 。這也就是為什么有了后面 Spark 基於 DAG 的 RDD 概念的崛起。
這里不得不多說一句,Hadoop 的文件系統 Hadoop Hdfs 才是 Hadoop MapReduce 的基礎,因為 Map Reduce 最實質的支撐其實就是這個 Hadoop Hdfs 。沒有它, Map Reduce 不過是空中閣樓。你看,在 Hadoop MapReduce 式微的今天,Hadoop Hdfs 還不是活得好好的,Spark 或是 Hive 這些工具也都是以它為基礎。不得不說,Hadoop Hdfs 才牛逼啊。
為什么會出現 Hadoop MapReduce
好了,接下來我們來探究一下為什么會出現 Hadoop MapReduce 這個東西。
MapReduce 在 Google 最大的應用是做網頁的索引。大家都知道 Google 是做搜索引擎起家的,而搜索引擎的基本原理就是索引,就是爬去互聯網上的網頁,然后對建立 單詞->文檔 的索引。這樣什么搜索關鍵字,才能找出對應網頁。這也是為什么 Google 會以 WordCount 作為 MapReduce 的例子。
既然明白搜索引擎的原理,那應該就明白自 2000 年來互聯網爆發的年代,單台機器肯定是不夠存儲大量的索引的,所以就有了分布式存儲,Google 內部用的叫 Gfs,Hadoop Hdfs 其實可以說是山寨 Gfs 來的。而在 Gfs 的基礎上,Hadoop MapReduce 的出現也就自然而然了。
推薦閱讀: