MepReduce架構及原理

1. MapReduce 定義
Hadoop中的MepReduce是一個使用簡單的軟件框架,基於它寫出來的程序能運行在由上千個機器組成的大型集羣上,並以一種可靠容錯並行處理TB級別的數據集。

2.MepReduce特點
1)MepReduce易於編程
它簡單的實現一些接口,就可以完成一個分佈式程序。這個分佈式程序可以分佈到大量的廉價PC上運行。也就是說你寫一個分佈式程序就跟寫一個簡單的串行程序是一樣的。
2)良好的擴展性
當你的計算機資源不能滿足時,可以通過簡單的增加機器來擴展它的計算能力。
3)高容錯性
MepReduce的設計初衷就是能將程序分佈到大量的廉價pc機上運行,這就要求它有很高的容錯性。比如其中的一臺機器掛了,它可以把上面的計算任務轉移到另一個節點上運行,不至於這個任務運行失敗。這個過程都是hadoop內部完成的。
4)適合PB級以上海量數據的離線處理
它適合離線處理而不適合在線處理。比如像毫秒級別的返回一個結果,MapReduce很難做到。
在有些場景下並不適合MapReduce來處理,如:
1.實時計算
MapReduce無法像MySql一樣在毫秒或秒級內返回結果。
2.流式計算
流式計算的輸入數據是動態的,而MapReduce的輸入數據集是靜態的,不能動態變化。這是因爲MapReduce自身的設計特點決定了數據源必須是靜態的。
3.DAG(有向圖)計算
多個應用程序存在依賴關係,後一個應用程序的輸入是前一個的輸出。在這種情況下,每個MapReduce作業的輸出結果都會寫入磁盤,會造成大量的磁盤IO,導致性能十分低下。

3.MapReduce 實例
爲了分析 MapReduce 的編程模型,這裏我們以 WordCount 爲實例。就像 Java、C++等編程語言的入門程序 hello word 一樣,WordCount 是 MapReduce 最簡單的入門程序。
下面我們就來逐步分析
1、場景:假如有大量的文件,裏面存儲的都是單詞。
類似應用場景:WordCount 雖然很簡單,但它是很多重要應用的模型。
1) 搜索引擎中,統計最流行的K個搜索詞。
2) 統計搜索詞頻率,幫助優化搜索詞提示。
2、任務:我們該如何統計每個單詞出現的次數?
3、將問題規範爲:有一批文件(規模爲 TB 級或者 PB 級),如何統計這些文件中所有單詞出現的次數。
4、解決方案:首先,分別統計每個文件中單詞出現的次數;然後,累加不同文件中同一個單詞出現次數。

4.MapReduce編程模型
通過上面的分析可知,它其實就是一個典型的 MapReduce 過程。下面我們通過示意圖來分析 MapReduce 過程
這裏寫圖片描述
上圖的流程大概分爲以下幾步:
1.假設一個文件有三行英文單詞作爲 MapReduce 的Input(輸入),這裏經過 Splitting過程把文件分割爲3塊。分割後的3塊數據就可以並行處理,每一塊交給一個 map 線程處理。
2.每個map線程中,以每個單詞作爲key,以1作爲value,之後輸出。
3.輸出的map要經過shuffling(混洗),將相同的單詞key放在一個桶裏,然後交給reduce進行處理。
4.reduce接收到shuffle後的數據後,會將相同的單詞進行合併,得到每個單詞的詞頻數,最後將統計好的每個單詞的詞頻數作爲輸出結果。
上述就是 MapReduce 的大致流程,前兩步可以看做map階段,後兩步可以看做reduce 階段。下面我們來看看MapReduce大致實現
1、Input:首先MapReduce輸入的是一系列key/value對。key表示每行偏移量,value代表每行輸入的單詞。
2、用戶提供了map函數和reduce函數的實現
map(k,v) ——> list(k1,v1)
reduce(k1,list(v1)) ——>(k2,v2)
map函數將每個單詞轉化爲key/value對輸出,這裏key爲每個單詞,value爲詞頻1。(k1,v1)是map輸出的中間key/value結果對。reduce將相同單詞的所有詞頻進行合併,比如將單詞k1,詞頻爲list(v1),合併爲(k2,v2)。reduce 合併完之後,最終輸出一系列(k2,v2)鍵值對。
下面我們來看一下 MapReduce 的僞代碼
    map(key,value):// map 函數,key代表偏移量,value代表每行單詞
    for each word w in value:// 循環每行數據,輸出每個單詞和詞頻的鍵值對(w,1)
    emit(w,1)

    reduce(key,values):// reduce 函數,key代表一個單詞,value代表這個單詞的所有詞頻數集合
    result=0
    for each count v in values: // 循環詞頻集合,求出該單詞的總詞頻數,然後輸出(key,result)
result+=v
    emit(key,result)
講到這裏,我們可以對 MapReduce 做一個總結:MapReduce將作業的整個運行過程分爲兩個階段:Map階段和Reduce階段。
1.Map階段
Map 階段是由一定數量的Map Task組成。這些Map Task可以同時運行,每個Map Task又是由以下三個部分組成。
1) 對輸入數據進行解析的組件:InputFormat
因爲不同的數據可能存儲的數據格式不一樣,就需要一個InputFormat組件來解析這些數據。默認情況下,它提供了一個TextInputFormat來解釋數據。TextInputFormat 就是我們前面提到的文本文件輸入格式,它會將文件的每一行解釋成(key,value),key代表每行偏移量,value代表每行數據內容。通常情況我們不需要自定義 InputFormat,因爲 MapReduce提供了很多種InputFormat的實現,我們根據不同的數據格式,選擇不同的 InputFormat 來解釋就可以了。
2)輸入數據處理:Mapper
這個Mapper是必須要實現的,因爲根據不同的業務對數據有不同的處理。
3)數據分組:Partitioner
Mapper 數據處理之後輸出之前,輸出key會經過Partitioner分組或者分桶選擇不同的reduce。默認的情況下,Partitioner會對map輸出的key進行hash取模,比如有6個Reduce Task,它就是模(mod)6,如果key的hash值爲0,就選擇第0個 Reduce Task,如果key的hash值爲1,就選擇第一個 Reduce Task。這樣不同的map對相同單詞key,它的hash值取模是一樣的,所以會交給同一個reduce來處理。
2.Reduce階段
Reduce階段由一定數量的Reduce Task組成。這些Reduce Task可以同時運行,每個 Reduce Task又是由以下四個部分組成。
1)數據遠程拷貝
Reduce Task要遠程拷貝每個map處理的結果,從每個map中讀取一部分結果。每個 Reduce Task拷貝哪些數據,是由上面 Partitioner 決定的。
2)數據按照key排序
Reduce Task讀取完數據後,要按照key進行排序。按照key排序後,相同的key被分到一組,交給同一個Reduce Task處理。
3) 數據處理:Reducer
以WordCount爲例,相同的單詞key分到一組,交個同一個Reducer處理,這樣就實現了對每個單詞的詞頻統計。
4) 數據輸出格式:OutputFormat
Reducer統計的結果,將按照OutputFormat格式輸出。默認情況下的輸出格式爲 TextOutputFormat,以WordCount爲例,這裏的key爲單詞,value爲詞頻數。
 InputFormat、Mapper、Partitioner、Reducer和OutputFormat 都是用戶可以實現的。通常情況下,用戶只需要實現 Mapper和Reducer,其他的使用默認實現就可以了。

5.MapReduce內部邏輯
下面我們通過MapReduce的內部邏輯,來分析MapReduce的數據處理過程。我們以WordCount爲例,來看一下mapreduce 內部邏輯,如下圖所示
這裏寫圖片描述
MapReduce 內部邏輯的大致流程主要由以下幾步完成
1、首先將 HDFS 中的數據以 Split 方式作爲 MapReduce 的輸入。以前文章提到,HDFS中的數據是以 block存儲,這裏怎麼又變成了以Split 作爲輸入呢?其實 block 是 HDFS 中的術語,Split 是 MapReduce 中的術語。默認的情況下,一個 Split 可以對應一個 block,當然也可以對應多個block,它們之間的對應關係是由 InputFormat 決定的。默認情況下,使用的是 TextInputFormat,這時一個Split對應一個block。 假設這裏有4個block,也就是4個Split,分別爲Split0、Split1、Split2和Split3。這時通過 InputFormat 來讀每個Split裏面的數據,它會把數據解析成一個個的(key,value),然後交給已經編寫好的Mapper 函數來處理。
2、每個Mapper 將輸入(key,value)數據解析成一個個的單詞和詞頻,比如(a,1)、(b,1)和(c,1)等等。
3、Mapper解析出的數據,比如(a,1),經過 Partitioner之後,會知道該選擇哪個Reducer來處理。每個 map 階段後,數據會輸出到本地磁盤上。
4、在reduce階段,每個reduce要進行shuffle讀取它所對應的數據。當所有數據讀取完之後,要經過Sort全排序,排序之後再交給 Reducer 做統計處理。比如,第一個Reducer讀取了兩個的(a,1)鍵值對數據,然後進行統計得出結果(a,2)。
5、將 Reducer 的處理結果,以OutputFormat數據格式輸出到 HDFS 的各個文件路徑下。這裏的OutputFormat默認爲TextOutputFormat,key爲單詞,value爲詞頻數,key和value之間的分割符爲”\tab”。 由上圖所示,(a 2)輸出到Part-0,(b 3)輸出到Part-1,(c 3)輸出到Part-2

6.MapReduce架構
  和HDFS一樣,MapReduce也是採用Master/Slave的架構,其架構圖如下所示
  這裏寫圖片描述
  MapReduce包含四個組成部分,分別爲Client、JobTracker、TaskTracker和Task,下面我們詳細介紹這四個組成部分。
  1)client客戶端
  每一個Job都會在客戶端通過client類將應用程序以及配置參數Configuration打包成Jar文件存儲在hdfs,並把路徑提交到JobTracker的master服務,然後由master創建每一個Task(即 MapTask 和 ReduceTask) 將它們分發到各個 TaskTracker 服務中去執行。
  2)JobTracker
  JobTracke負責資源監控和作業調度。JobTracker 監控所有TaskTracker 與job的健康狀況,一旦發現失敗,就將相應的任務轉移到其他節點;同時,JobTracker 會跟蹤任務的執行進度、資源使用量等信息,並將這些信息告訴任務調度器,而調度器會在資源出現空閒時,選擇合適的任務使用這些資源。在Hadoop中,任務調度器是一個可插拔的模塊,用戶可以根據自己的需要設計相應的調度器。
  3)TaskTracker
  TaskTracker 會週期性地通過Heartbeat 將本節點上資源的使用情況和任務的運行進度彙報給JobTracker,同時接收JobTracker 發送過來的命令並執行相應的操作(如啓動新任務、殺死任務等)。TaskTracker 使用”slot”等量劃分本節點上的資源量。”slot”代表計算資源(CPU、內存等)。一個Task 獲取到一個slot 後纔有機會運行,而Hadoop 調度器的作用就是將各個TaskTracker 上的空閒slot分配給Task 使用。slot分爲Map slot 和Reduce slot 兩種,分別供Map Task 和Reduce Task 使用。TaskTracker 通過slot 數目(可配置參數)限定Task 的併發度。
  4)Task
  Task 分爲Map Task 和Reduce Task 兩種,均由TaskTracker 啓動。HDFS 以固定大小的block 爲基本單位存儲數據,而對於MapReduce 而言,其處理單位是split。split 是一個邏輯概念,它只包含一些元數據信息,比如數據起始位置、數據長度、數據所在節點等。它的劃分方法完全由用戶自己決定。但需要注意的是,split 的多少決定了Map Task 的數目,因爲每個split 只會交給一個Map Task 處理。Split 和 Block的關係如下圖所示
  這裏寫圖片描述
  Map Task 執行過程如下圖 所示:由該圖可知,Map Task 先將對應的split 迭代解析成一個個key/value 對,依次調用用戶 自定義的map() 函數進行處理,最終將臨時結果存放到本地磁盤上, 其中臨時數據被分成若干個partition,每個partition 將被一個Reduce Task 處理
  這裏寫圖片描述
  Reduce Task 執行過程下圖所示。該過程分爲三個階段:
1)從遠程節點上讀取Map Task 中間結果(稱爲”Shuffle 階段”);
2)按照key 對key/value 對進行排序(稱爲”Sort 階段”);
3)依次讀取< key, value list>,調用用戶自定義的reduce() 函數處理,並將最終結果存到HDFS 上(稱爲”Reduce 階段”)
這裏寫圖片描述  

7.MapReduce框架的容錯性
MapReduce 最大的特點之一就是有很好的容錯性,即使你的節點掛掉了1個、2個、3個,都是沒有問題的, 它都可以照常來運行,把你的作業或者應用程序運行完成。不會出現某個節點掛了,你的作業就運行失敗這種情況。 那麼 MapReduce 到底是通過什麼樣的機制,使它具有這麼好的容錯性呢?下面我們依次來介紹一下。
1、JobTracker
很不幸,JobTracker 存在單點故障,一旦出現故障,整個集羣就不可用。這個是1.0裏面出現的問題,在2.0裏面這個問題已經得到了解決。不過大家放心,即使在1.0中,MapReduce也不會經常出現故障。它可能一年也就是出現幾次故障,出現故障之後,你重啓一下,再把作業重新提交就可以了,它不會像 HDFS 那樣出現數據的丟失。 因爲 MapReduce 是一個計算框架,計算過程是可以重現的,即使某個服務掛掉了,你重啓一下服務,然後把作業重新提交,也是不會影響你的業務的。
2、TaskTracker
 TaskTracker 週期性的向 JobTracker 彙報心跳,如果一定的時間內沒有彙報這個心跳,JobTracker 就認爲該TaskTracker 掛掉了,它就會把上面所有任務調度到其它TaskTracker(節點)上運行。這樣即使某個節點掛了,也不會影響整個集羣的運行。
 3、MapTask和ReduceTask
 MapTask和ReduceTask 也可能運行掛掉。比如內存超出了或者磁盤掛掉了,這個任務也就掛掉了。這個時候 TaskTracker 就會把每個MapTask和ReduceTask的運行狀態回報給 JobTracker,JobTracker 一旦發現某個Task掛掉了,它就會通過調度器把該Task調度到其它節點上。這樣的話,即使任務掛掉了,也不會影響應用程序的運行。

8、MapReduce資源組織方式

  MapReduce 計算框架並沒有直接調用 CPU和內存等多維度資源,它把多維度資源抽象爲 “slot”,用 “slot” 來描述資源的數量。管理員可以在每個節點上單獨配置slot個數。slot可以分爲map slot和reduce slot。從一定程度上,slot可以看做”任務運行並行度”。如果某個節點配置了5個map slot,那麼這個節點最多運行5個Map Task;如果某個節點配置了3個reduce slot,那麼該節點最多運行3個Reduce Task。下面我們分別介紹 Map slot和Reduce slot。

 1、Map slot
1)Map slot可用於運行 Map Task的資源,而且只能運行Map Task。
2)每個Map Task通常使用一個map slot。而比如像容量調度器,它可以有比較大的 MapTask。這樣的MapTask使用內存比較多,那麼它可能使用多個map slot。

 2、Reduce slot
1)Reduce slot 可用於運行ReduceTask,而且只能運行ReduceTask。
2)每個ReduceTask通常使用一個reduce slot。而比如像容量調度器,它可以有比較大的 ReduceTask。這樣的ReduceTask使用內存比較多,那麼它可能使用多個reduce slot

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章