????MapRduce是hadoop中的一個(gè)分布式計(jì)算工具,分為map階段和reduce階段其采用了一個(gè)分而治之的思想
???? 以下一個(gè)例子作為演示,假設(shè)有一個(gè)涉及300M的文件(1.txt200m 2.txt 100m)
進(jìn)行計(jì)算,求每個(gè)單詞所占的個(gè)數(shù)


Map階段

1.首先進(jìn)行邏輯切片,切片個(gè)數(shù)就是maptask啟動(dòng)的個(gè)數(shù)
2.maptask通過textinputformat按行讀取分區(qū)當(dāng)中的數(shù)據(jù),結(jié)果是一個(gè)鍵值對(duì)<k1,v1> (k1是偏移量地址,value是具體的數(shù)據(jù))
3,textinputformat將讀取的鍵值對(duì)結(jié)果傳個(gè)業(yè)務(wù)代碼進(jìn)行處理,處理的結(jié)果是一個(gè)新的鍵值對(duì)<k2,v2>
4,處理結(jié)果經(jīng)過partition分區(qū)(默認(rèn)只要一個(gè))傳送給緩沖區(qū)
5,緩沖區(qū)(默認(rèn)大小100M)內(nèi)的數(shù)據(jù)達(dá)到百分之八十,會(huì)產(chǎn)生一次數(shù)據(jù)溢出.溢出的數(shù)據(jù)經(jīng)過排序存儲(chǔ)到磁盤當(dāng)中的一個(gè)臨時(shí)文件
6,當(dāng)區(qū)中數(shù)據(jù)處理完成后,會(huì)把所有的臨時(shí)文件merge合并到一個(gè)最終結(jié)果文件
reduce階段

1,reducetask拉取(copy)maptask最終的結(jié)果集
2,合并:把拉取的數(shù)據(jù)Merge合并成為一個(gè)文件
3,排序:按照對(duì)應(yīng)key值進(jìn)行排序
4,分組:key一樣的分為一組
5,每個(gè)組都調(diào)用業(yè)務(wù)代碼處理一次,處理完的數(shù)據(jù)是一個(gè)新的鍵值對(duì)
6,處理結(jié)果通過TextOutputformat 存儲(chǔ)到磁盤指定位置
思考:maptask 個(gè)數(shù)與文件大小,文件個(gè)數(shù),邏輯分區(qū)大小有關(guān),分區(qū)大小默認(rèn)為hdfs分塊大小,可以改
shuffle過程

shuffle:指的是map產(chǎn)生輸出到reduce取得數(shù)據(jù)輸入之前的過程
map階段:
collect收集:把數(shù)據(jù)寫入緩沖區(qū)階段寫入的是partition分區(qū)信息和key/value
partition分區(qū): 跟reducetask的個(gè)數(shù)有關(guān),reduce task又跟業(yè)務(wù)需要有關(guān)可以自定義
spill 溢出:當(dāng)緩存區(qū)的數(shù)據(jù)達(dá)到80%會(huì)溢出,溢出的數(shù)據(jù)從內(nèi)存中寫入磁盤,如果配置了combiner規(guī) 約會(huì)按照分區(qū)和規(guī)約進(jìn)行排序
merge 合并:把磁盤當(dāng)中的這些臨時(shí)文件合并成一個(gè)總的結(jié)果文件
reduce階段:
copy拉取數(shù)據(jù)
merge 合并
sort 排序
geouping 分組
拓展- partition分區(qū)的個(gè)數(shù)影響因素

默認(rèn)情況下分區(qū)只有一個(gè),reducetask只有一個(gè)意味著最終處理結(jié)果輸出在一個(gè)文件上,此時(shí)沒有分區(qū)的概念.

用戶也可以根據(jù)需求去設(shè)置MR程序中reducetask的個(gè)數(shù) job.setNumarenducetask(n>2)
此時(shí)對(duì)于maptask來說,處理完的數(shù)據(jù)到底要去哪里,這個(gè)問題就是partition分區(qū)問題
分區(qū)的默認(rèn)規(guī)則:
哈希取余<key,value>
key.hash % reducetask 個(gè)數(shù) -->余數(shù)(分區(qū)編號(hào))
默認(rèn)規(guī)則不能保證數(shù)據(jù)平均分配也無(wú)法保證是否符合業(yè)務(wù)需求,但是能保證key一樣 分區(qū)一樣
自定義規(guī)則:
根據(jù)具體需求定義
在Map任務(wù)和Reduce任務(wù)的過程中,一共發(fā)生了3次排序
1)當(dāng)map函數(shù)產(chǎn)生輸出時(shí),會(huì)首先寫入內(nèi)存的環(huán)形緩沖區(qū),當(dāng)達(dá)到設(shè)定的閥值,在刷寫磁盤之前,后臺(tái)線程會(huì)將緩沖區(qū)的數(shù)據(jù)劃分成相應(yīng)的分區(qū)。在每個(gè)分區(qū)中,后臺(tái)線程按鍵進(jìn)行內(nèi)排序
2)在Map任務(wù)完成之前,磁盤上存在多個(gè)已經(jīng)分好區(qū),并排好序的,大小和緩沖區(qū)一樣的溢寫文件,這時(shí)溢寫文件將被合并成一個(gè)已分區(qū)且已排序的輸出文件。由于溢寫文件已經(jīng)經(jīng)過第一次排序,所有合并文件只需要再做一次排序即可使輸出文件整體有序。
3)在reduce階段,需要將多個(gè)Map任務(wù)的輸出文件copy到ReduceTask中后合并,由于經(jīng)過第二次排序,所以合并文件時(shí)只需再做一次排序即可使輸出文件整體有序
在這3次排序中第一次是內(nèi)存緩沖區(qū)做的內(nèi)排序,使用的算法使快速排序,第二次排序和第三次排序都是在文件合并階段發(fā)生的,使用的是歸并排序。