書接上回,繼續為大家講解MapReduce使用者程式設計介面
MapReduce – 使用者程式設計介面
下面將著重談下MapReduce框架中使用者經常使用的一些介面或類的詳細內容。 瞭解這些會極大説明你實現、配置和優化MR任務。 當然javadoc中對每個class或介面都進行了更全面的陳述,這裡只是一個指引教程。
首先來看下Mapper和Reducer介面,通常MR應用都要實現這兩個介面來提供map和reduce方法,這些是MRJob的核心部分。
Mapper
Mapper 將輸入的kv對映射成中間資料kv對集合。 Maps 將輸入記錄轉變為中間記錄,其中被轉化後的記錄不必和輸入記錄類型相同。 一個給定的輸入對可以映射為0或者多個輸出對。
在MRJob執行過程中,MapReduce框架根據提前指定的InputFormat(輸入格式物件)產生InputSplit(輸入分片),而每個InputSplit將會由一個map任務處理。
總起來講,Mapper實現類通過JobConfigurable.configure(JobConf)方法傳入JobConf物件來初始化,然後在每個map任務中調用map(WritableComparable, Writable,OutputCollector,Reporter)方法處理InputSplit的每個kv對。 MR應用可以覆蓋Closeable.close方法去處理一些必須的清理工作。
輸出對不一定和輸入對類型相同。 一個給定的輸入對可能映射成0或者很多的輸出對。 輸出對是框架通過調用OutputCollector.colect(WritableComparable,Writable)得到。
MR應用可以使用Reporter彙報進度,設置應用層級的狀態資訊,更新計數器或者只是顯示應用處于運行狀態等。
所有和給定的輸出key關聯的中間資料都會隨後被框架分組處理,並傳給Reducer處理以產生最終的輸出。 使用者可以通過JobConf.setOutputKeyComparatorClass(Class)指定一個Comparator控制分組處理過程。
Mapper輸出都被排序後根據Reducer數量進行分區,分區數量等於reduce任務數量。 使用者可以通過實現自訂的Partitioner來控制哪些keys(記錄)到哪個Reducer中去。
此外,使用者還可以指定一個Combiner,調用JobConf.setCombinerClass(Class)來實現。 這個可以來對map輸出做本地的聚合,有助於減少從mapper到reducer的資料量。
經過排序的中間輸出資料通常以一種簡單的格式(key-len,key,HTTP://www.aliyun.com/zixun/aggregation/9541.html">value-len,value)存儲。 應用可以決定是否或者怎樣被壓縮以及壓縮格式,可以通過JobConf來指定.
Map數
通常map數由輸入資料總大小決定,也就是所有輸入檔的blocks數目決定。
每個節點並行的運行的map數正常在10到100個。 由於Map任務初始化本身需要一段時間所以map執行時間至少在1分鐘為好。
如此,如果有10T的資料檔案,每個block大小128M,最大使用為82000map數,除非使用setNumMapTasks(int)(這個方法僅僅對MR框架提供一個建議值)將map數值設置到更高。
Reducer
Reducer 根據key將中間資料集合處理合併為更小的資料結果集。
使用者可以通過JobConf.setNumReduceTasks(int)設置作業的reducer數目。
整體而言,Reducer實現類通過JobConfigurable.configure(JobConf)方法將JobConf物件傳入,並為Job設置和初始化Reducer。 MR框架調用 reduce(WritableComparable, Iterator, OutputCollector, Reporter) 來處理以key被分組的輸入資料。 應用可以覆蓋Closeable.close()處理必要的清理操作。
Reducer由三個主要階段組成:shuffle,sort,reduce。
shuffle
輸入到Reducer的輸入資料是Mapper已經排過序的資料.在shuffle階段,框架根據partition演算法獲取相關的mapper位址,並通過Http協定將資料由reducer拉取到reducer機器上處理。
sort
框架在這個階段會根據key對reducer的輸入進行分組(因為不同的mapper輸出的資料中可能含有相同的key)。
shuffle和sort是同時進行的,同時reducer仍然在拉取map的輸出。
Secondary Sort
如果對中間資料key進行分組的規則和在處理化簡階段前對key分組規則不一致時,可以通過 JobConf.setOutputValueGroupingComparator(Class)設置一個Comparator。 因為中間資料的分群組原則是通過 JobConf.setOutputKeyComparatorClass(Class) 設置的,可以控制中間資料根據哪些key進行分組。 而JobConf.setOutputValueGroupingComparator(Class)則可用於在資料連線情況下對值進行二次排序。
Reduce(化簡)
這個階段框架迴圈調用 reduce(WritableComparable, Iterator, OutputCollector, Reporter) 方法處理被分組的每個kv對。
reduce 任務一般通過 OutputCollector.collect(WritableComparable, Writable)將輸出資料寫入檔案系統FileSystem。
應用可以使用Reporter彙報作業執行進度、設置應用層級的狀態資訊並更新計數器(Counter),或者只是提示作業在運行。
注意,Reducer的輸出不會進行排序。
Reducer數目
合適的reducer數目可以這樣估算:
(節點數目mapred.tasktracker.reduce.tasks.maximum)乘以0.95 或 乘以1.75。
因數為0.95時,當所有map任務完成時所有reducer可以立即啟動,並開始從map機器上拉取資料。 因數為1.75時,最快的一些節點將完成第一輪reduce處理,此時框架開始啟動第二輪reduce任務,這樣可以達到比較好的作業負載均衡。
提高reduce數目會增加框架的運行負擔,但有利於提升作業的負載均衡並降低失敗的成本。
上述的因數使用最好在作業執行時框架仍然有reduce槽為前提,畢竟框架還需要對作業進行可能的推測執行和失敗任務的處理。
不使用Reducer
如果不需要進行化簡處理,可以將reduce數目設為0。
這種情況下,map的輸出會直接寫入到檔案系統。 輸出路徑通過setOutputPath(Path)指定。 框架在寫入資料到檔案系統之前不再對map結果進行排序。
Partitioner
Partitioner對資料按照key進行分區,從而控制map的輸出傳輸到哪個reducer上。 預設的Partitioner演算法是hash(雜湊。 分區數目由作業的reducer數目決定。
HashPartitioner 是預設的Partitioner。
Reporter
Reporter為MR應用提供了進度報告、應用狀態資訊設置,和計數器(Counter)更新等功能.
Mapper和Reducer實現可以使用Reporter彙報進度或者提示作業在正常運行。 在一些場景下,應用在處理一些特殊的kv對時耗費了過多時間,這個可能會因為框架假定任務超時而強制停止了這些作業。 為避免該情況,可以設置mapred.task.timeout 為一個比較高的值或者將其設置為0以避免超時發生。
應用也可以使用Reporter來更新計數(Counter)。
OutputCollector
OutputCollector是MR框架提供的通用工具來收集Mapper或者Reducer輸出資料(中間資料或者最終結果資料)。
Hadoop MapReduce提供了一些經常使用的mapper、reducer和partioner的實現來。 這些工具可以點擊這裡進行學習。
英文原文:cloudera