MapReduce計算模型二 MapReduce框架Hadoop應用(一)

以前寫過關於Hadoop方面的MapReduce框架的文章MapReduce框架Hadoop應用(一) 介紹了MapReduce的模型和Hadoop下的MapReduce框架,此文章將進一步介紹mapreduce計算模型能用於解決什麼問題及有什麼巧妙優化。html

MapReduce到底解決什麼問題?

MapReduce準確的說,它不是一個產品,而是一種解決問題的思路,可以用分治策略來解決問題。例如:網頁抓取、日誌處理、索引倒排、查詢請求彙總等等問題。經過分治法,將一個大規模的問題,分解成多個小規模的問題(分),多個小規模問題解決,再統籌小問題的解(合),就可以解決大規模的問題。最先在單機的體系下計算,當輸入數據量巨大的時候,處理很慢。如何可以在短期內完成處理,很容易想到的思路是,將這些計算分佈在成百上千的主機上,但此時,會遇到各類複雜的問題,例如:併發計算、數據分發、錯誤處理、數據分佈、負載均衡、集羣管理與通訊等,將這些問題綜合起來將是比較複雜的問題了,而Google爲了方便用戶使用系統,提供給了用戶不多的接口,去解決複雜的問題。網絡

    (1) Map函數接口:處理一個基於key/value(後簡稱k/v)的數據對(pair)數據集合,同時也輸出基於k/v的數據集合。併發

    (2) Reduce函數接口:用來合併Map輸出的k/v數據集合負載均衡

假設咱們要統計大量文檔中單詞出現的次數框架

  Map函數

    輸入K/V:pair(文檔名稱,文檔內容)oop

    輸出K/V:pair(單詞,1)post

  Reduce優化

    輸入K/V:pair(單詞,1)url

    輸出K/V:pair(單詞,總計數) 

  Map僞代碼:

Map(list<pair($docName, $docContent)>){//若是有多個Map進程,輸入能夠是一個pair,不是一個list
        foreach(pair in list)
                foreach($word in $docContent)
                        print pair($word, 1); // 輸出list<k,v>
}            

  Reduce僞代碼:

Reduce(list<pair($word, $count)>){//大量(word,1)(即便有多個Reduce進程,輸入也是list<pair>,由於它的輸入是Map的輸出)
    map<string,int> result;
        foreach(pair in list)
         if result.isExist($word)
             result[$word] += $count;          else              result[$word] = 1; foreach($keyin result) print pair($key, result[$key]); //輸出list<k,v> }

  

  能夠看到,R個reduce實例併發進行處理,直接輸出最後的計數結果。須要理解的是,因爲這是業務計算的最終結果,一個單詞的計數不會出如今兩個實例裏。即:若是(a, 256)出如今了實例1的輸出裏,就必定不會出如今其餘實例的輸出裏,不然的話,還須要合併,就不是最終結果。

  再看中間步驟,map到reduce的過程,M個map實例的輸出,會做爲R個reduce實例的輸入。

  問題一:每一個map都有可能輸出(a, 1),而最終結果(a, 256)必須由一個reduce輸出,那如何保證每一個map輸出的同一個key,落到同一個reduce上去呢?

    這就是「分區函數」的做用。分區函數是使用MapReduce的用戶按所需實現的,決定map輸出的每個key應當落到哪一個reduce上的函數。若是用戶沒有實現,會使用默認分區函數。爲了保證每個reduce實例都可以差很少時間結束工做任務,分區函數的實現要點是:儘可能負載均衡,即數據均勻分攤,防止數據傾斜形成部分reduce節點數據飢餓。若是數據不是負載均衡的,那麼有些reduce實例處理的單詞多,有些reduce處理的單詞少,這樣就可能出現全部reduce實例都處理結束,最後等待一個須要長時間處理的reduce狀況。

  問題二:每一個map都有可能輸出多個(a, 1),這樣就增大了網絡帶寬資源以及reduce的計算資源,怎麼辦?

    這就是「合併函數」的做用。有時,map產生的中間key的重複數據比重很大,能夠提供給用戶一個自定義函數,在一個map實例完成工做後,本地就作一次合併,這樣將大大節約網絡傳輸與reduce計算資源。合併函數在每一個map任務結束前都會執行一次,通常來講,合併函數與reduce函數是同樣的,區別是:合併函數是執行map實例本地數據合併,而reduce函數是執行最終的合併,會收集多個map實例的數據。對於詞頻統計應用,合併函數能夠將:一個map實例的多個(a, 1)合併成一個(a, count)輸出。

  問題三:如何肯定文件到map的輸入呢?

    隨意便可,只要負載均衡,均勻切分輸入文件大小就行,不用管分到哪一個map實例都能正確處理

  問題四:map和reduce可能會產生不少磁盤io,將更適用於離線計算,完成離線做業。

相關文章
相關標籤/搜索