2個關(guān)鍵問題
- 如何為每個數(shù)據(jù)塊分配一個Map栅干,也就是代碼怎么發(fā)送到數(shù)據(jù)塊所在服務(wù)器迈套,發(fā)送后如何啟動,啟動后如何直到數(shù)據(jù)在什么位置
- 處于不同服務(wù)器的map輸出的<Key, Value>非驮,如何把相同的Key聚合在一起發(fā)送給Reduce任務(wù)
MapReduce作業(yè)啟動和運(yùn)行機(jī)制
MapReduce數(shù)據(jù)合并與連接機(jī)制
shuffle
每個 Map 任務(wù)的計(jì)算結(jié)果都會寫入到本地文件系統(tǒng)交汤,等 Map 任務(wù)快要計(jì)算完成的時候,MapReduce 計(jì)算框架會啟動 shuffle 過程劫笙,在 Map 任務(wù)進(jìn)程調(diào)用一個 Partitioner 接口芙扎,對 Map 產(chǎn)生的每個 <Key, Value> 進(jìn)行 Reduce 分區(qū)選擇,然后通過 HTTP 通信發(fā)送給對應(yīng)的 Reduce 進(jìn)程填大。這樣不管 Map 位于哪個服務(wù)器節(jié)點(diǎn)戒洼,相同的 Key 一定會被發(fā)送給相同的 Reduce 進(jìn)程。Reduce 任務(wù)進(jìn)程對收到的 <Key, Value> 進(jìn)行排序和合并允华,相同的 Key 放在一起圈浇,組成一個 <Key, Value 集合 > 傳遞給 Reduce 執(zhí)行。
map 輸出的 <Key, Value>shuffle 到哪個 Reduce 進(jìn)程是這里的關(guān)鍵靴寂,它是由 Partitioner 來實(shí)現(xiàn)磷蜀,MapReduce 框架默認(rèn)的 Partitioner 用 Key 的哈希值對 Reduce 任務(wù)數(shù)量取模,相同的 Key 一定會落在相同的 Reduce 任務(wù) ID 上百炬。從實(shí)現(xiàn)上來看的話褐隆,這樣的 Partitioner 代碼只需要一行。
public int getPartition(K2 key, V2 value, int numReduceTasks){
return (key.hashCode()) & Integer.MAX_VALUE) % numReduceTasks;
}