MapReduce簡介
Hadoop MapReduce是一個軟件框架,基於該框架能夠容易地編寫應用程序,這些應用程序能夠運行在由上千個商用機器組成的大集羣上,並以一種可靠的,具有容錯能力的方式並行地處理上TB級別的海量數據集。
MapReduce是一種分佈式計算模型,是Google提出的,主要用於搜索領域,解決海量數據的計算問題。
MR有兩個階段組成:Map和Reduce,用戶只需實現map()和reduce()兩個函數,即可實現分佈式計算。
Hadoop四大組件
首先讓我們來重溫一下 hadoop 的四大組件:
HDFS:分佈式存儲系統
MapReduce:分佈式計算系統
YARN: hadoop 的資源調度系統
Common: 以上三大組件的底層支撐組件,主要提供基礎工具包和 RPC 框架等
Mapreduce 是一個分佈式運算程序的編程框架,是用戶開發“基於 hadoop 的數據分析 應用”的核心框架
Mapreduce 核心功能是將用戶編寫的業務邏輯代碼和自帶默認組件整合成一個完整的 分佈式運算程序,併發運行在一個 hadoop 集羣上
MapReduce的思想
主要思想:分而治之,分久必合
核心思想:相同的key爲一組,調用一次reduce方法,方法內迭代這一組數據進行計算
(1)Mapper負責“分”,即把複雜的任務分解爲若干個“簡單的任務”來處理。“簡單的任務”包含三層含義:
一是數據或計算的規模相對原任務要大大縮小;
二是就近計算原則,即任務會分配到存放着所需數據的節點上進行計算;
三是這些小任務可以並行計算,彼此間幾乎沒有依賴關係。
(2)Reducer負責對map階段的結果進行彙總。至於需要多少個Reducer,用戶可以根據具體問題,通過在mapred-site.xml配置文件裏設置參數mapred.reduce.tasks的值,缺省值爲1。
MapReduce的工作機制
shuffle write階段
1,block ≈split切片=map task
默認buffer的大小是100M
2,map task將處理後每一條記錄打上標籤,上標籤的目的就是爲了讓這一條知道將來被哪一個reduce task處理
打標籤:分區
分區是由分區器來完成的
默認的分區器:HashPartitioner
分區策略:根據key的hashcode與reduce task Num 取模
3,進入buffer之後的每一條記錄是由三部分組成的:
①分區號
②key
③value
4,溢寫過程:
portitions=combinner->sort->spill
即=小聚合+排序+歸併
map task 一條條的往buffer中去寫,一旦寫入到80M,此時他將會把這80M的內存進行封鎖,封鎖後會對內存中的數據進行combiner(小聚合)。
排序:分區號、key
將相同分區號的數據放在一起,並且對分區內的數據進行排序
以上的combiner以及排序完成後,就開始溢寫數據到磁盤上
此時的磁盤文件就是根據分區號分好區的,並且是內部有序的文件。
注意:沒進行一次溢寫就會產生一個小的磁盤文件。
5,歸併
map task計算完畢後,會將磁盤上的小文件合併成一個大文件,在合併的時候會使用歸併排序的算法,將各個小文件合併成一個有序的大文件
每一個map task都會經過剛纔所說的一切,也就是每一個map task都會產生一個有分區的並且有序的大文件。
shuffle read階段
去map端讀取相應的分區數據,將分區數據寫入到內存中,內存滿了就會溢出,溢出之前會排序,當把所有的數據取來之後,會將溢出產生的磁盤小文件合併,排序成有序的大文件。
why要合併產生一個有序的大文件?
原因:就是爲了提高分組的分組效率
歸根來說,這四次排序都是爲了提高分組的分組效率。
最後每一組數據再調用一次reduce函數,產生結果,此時reduce要處理的文件,經過前三次的排序,內部都是有序的,且經過合併,文件的數量也大大減少,所以極大地加快了最後reduce函數排序的過程。
MapReduce的計算框架
hadoop 1.0版本
jobTracker的作用:
1,負責資源調度 主節點 一旦故障 整個集羣癱瘓了
2,負責任務調度,主節點
問題:
1,負載過高,容易故障
2,與MR的耦合度太高,如果spark也要運行在這套框架上,需要自己去實現,這個集羣就存在兩套資源調度器,就會出現資源隔離問題以及資源搶奪問題。
這種設計模式,jobTracker既做資源調度,又做任務調度,這樣就會造成job的壓力很大,一旦jobTracker節點掛掉,整個計算框架就掛了,歸根結底還是單點故障問題。
除此之外,如果當jobTracker分配資源任務的時候,又來了一個application應用請求計算框架分配資源,這個時候就會出現資源隔離和資源搶奪問題。
hadoop 2.0之後版本
hadoop 2.0之後採用yarn集羣來進行資源調度分配
大體流程:
1,client拿到Application計算文件的路徑找到NN獲取每一個block的位置
2,找到RM爲ApplicationMaster申請資源
3,RM接受客戶端的申請,然後查看哪一個節點上的資源充足,如果大部分節點的資源充足,那就隨機找一臺節點啓動contain容器。
4,在node01處規劃一個container以後,MM會在這個容器中啓動一個ApplicationMaster(主要負責任務調度)
5,client會將生成的報表交給AM
6,AM拿到報表後會根據報表去找RM申請資源
7,AM分發map task到各個yarn-child中執行
8,最後經過map task會產生一個個攜帶分區號,內部有序的磁盤小文件。
優點:
這種方式,把資源調度和任務調度分開,在不同節點上進行,這樣極大地減輕了單節點的負擔,故障發生的概率也相對的減少了。
此外把applicationMaster放到隨機的一個datenode節點,因爲本身節點就存儲了一部分數據,所以又可以減少網絡IO。
還有就是爲了解決資源調度器的單調故障問題,我們又採用zookeeper集羣的形式,對其做監管和備份,一旦RM掛掉,就會立即啓動備份的RM.
MapReduce的框架的優點
- 易於編程,用戶通常情況下只需要編寫Mapper和Reducer程序即可。
- 良好的擴展性,即可以很容易的增加節點
- 高容錯性,一個Job默認情況下會嘗試啓動兩次,一個mapper或者reducer默認會嘗試4次,如果一個節點掛了,可以向系統申請新的節點來執行這個mapper或者reducer
- 適合PB級別的數據的離線處理
MapReduce編程模型
Map階段:
- 輸入數據的解析:InputFormat
- 輸入數據處理:Mapper輸入數據處理:Mapper
- 輸入分組:Partitioner輸入分組:Partitioner
- 本節點的規約:Combiner ,本節點的規約:Combiner ,
Reduce階段:
- Shuffling階段拉取數據
- 排序,溢寫
- Reducer數據規約:Reducer
- 數據輸出格式: OutputFormat
詳細介紹:
InputFormat
將文件進行分片,InputSplit方法,處理跨行問題
將分片數據解析成key/val 對,默認實現是TextInputFormat,其中key是句柄偏移量,value是行內容
關於Split和Block的解釋
默認情況下Split就是HDFS中的一個Block,但是用戶可以自定義Split與Block的對應關係,split切片是邏輯
上的切,並沒有真正的去切割數據。
理解Partitioner
Partitioner決定了Mapper的每條輸出數據交由那個Reduce程序進行處理,默認情況下是通過
hash(key)mode R
R 是 Reduce Task 的數目
Map函數與Reduce函數:
函數 | 輸入 | 輸入 | 說明 |
---|---|---|---|
Map | <“k1”,v1> 如:<行號,”a b c”> |
List(<"k2,"v2>) 如:<“a”,1> <“b”,1> <“c”,1> |
1.將小數據集進一步解析成一批<key,value>對,輸入Map函數中進行處理 2.每一個輸入的<"k1,v1>會輸出一批<k2,v2>。<k2,v2>是計算的中間結果 |
Reduce | <k2,List(v2)> 如:<“a”,<1,1,1>> |
<k3,v3><“a”,3> | 輸入的中間結果<k2,List(v2)>中的List(v2)表示是一批屬於同一個k2的value |
問題:
Yarn下的mapper和reducer併發執行個數由什麼決定的呢?
由調度的資源決定的,也就是說啓動的YarnChild個數多少取決於資源的分配和free的資源量
map個數主要由任務切片spilt決定的,默認情況下一個split的大小就是block由參與任務的文件個數決定的。
分區與分組的概念
分區的目的是根據Key值決定Mapper的輸出記錄被送到哪一個Reducer上去處理。而分組的就比較好理解了。分組就是與記錄的Key相關。在同一個分區裏面,具有相同Key值的記錄是屬於同一個分組的。
默認情況下key值相同爲一組,但也可以自定義分組,比如我們天氣的例子:找出一個月中溫度最高的兩天,我們分組就是按照年和月進行分組的,同一年同一月的爲一組。