map-reduce的八个流程
生活随笔
收集整理的這篇文章主要介紹了
map-reduce的八个流程
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
下面講解這八個(gè)流程
?Inputformat——》map——》(combine)——》partition——》copy&merge——》sort——》reduce——》outputformat
FileSplit:文件的子集--文件分割體
0. 簡(jiǎn)介:
這篇文檔描述在hadoop中map和reduce操作是怎樣具體完成的。如果你對(duì)Google的MapReduce各式模式不熟悉,請(qǐng)先參閱MapReduce--http://labs.google.com/papers/mapreduce.html
1.MAP
1.1 Map階段
由于Map是并行地對(duì)輸入的文件集進(jìn)行操作,所以它的第一步(FileSplit) 就是把文件集分割成一些子集.如果一個(gè)單個(gè)的文件大到它已影響到查找效率時(shí),它會(huì)被分割成一些小的分割體。要指出的是分割這個(gè)一步是不知道輸入文件的內(nèi)部邏輯結(jié)構(gòu)的,比如,以行為邏輯分割的文本文件會(huì)被以任意的字節(jié)界限分割,所以這個(gè)具體分割要自己去指定也可以用hadoop已經(jīng)定義的幾個(gè)簡(jiǎn)單分割。然后每個(gè)文件分割體都會(huì)對(duì)應(yīng)地有一個(gè)新的map任務(wù)。當(dāng)單個(gè)map任務(wù)開始時(shí),它會(huì)對(duì)每個(gè)配置過的reduce任務(wù)開啟一個(gè)新的輸出書寫器(writer).緊接著它(writer)會(huì)用從指定的特定InputFormat里得到的RecordReader去讀它的文件分割體。InputFormat類分析輸入文件并產(chǎn)生key-value鍵值對(duì).同時(shí)InputFormat必需要處理在以文件分割時(shí)邊界處的記錄。比如TextInputFormat會(huì)讀取分割邊界的文件分割體有最后一行,如果當(dāng)讀取的分割體不是第一個(gè)時(shí),TextInputFormat會(huì)忽略第一行的內(nèi)容。
InputFormat類并不需要產(chǎn)生一些對(duì)有意義的鍵值對(duì)。比如TextInputFormat類的默認(rèn)輸出是以輸入文本的行內(nèi)容為value,以行偏移量為key--大多數(shù)應(yīng)用只用到而很少用到偏移量。
傳給用戶配置的mapper的鍵值對(duì)都是從RecordReader讀入的,用戶提供的Mapper類就可以對(duì)鍵值對(duì)進(jìn)行任意的操作再調(diào)用OutputCollector.collect方法來重新收集自己定義后的鍵值對(duì)。產(chǎn)生的輸出必需用一個(gè)Key類和一個(gè)value類,這是因?yàn)镸ap的輸出結(jié)果要被以SequenceFile的形式寫入磁盤,這種形式包括每個(gè)文件的類型信息和所有的記錄都是同類形的(如果你想輸出不同的數(shù)據(jù)結(jié)構(gòu)你可以繼承個(gè)子類出來)。Map的輸入和輸出鍵值對(duì)不需要在類型上有聯(lián)系.
當(dāng)Mapper的輸出被收集后,它們會(huì)被Partitioner類以指定的方式區(qū)分地寫出到輸出文件里。默認(rèn)是以HashPartitioner類用key類的哈希函數(shù)產(chǎn)生的hashcode來區(qū)分(因此就要有一個(gè)很好的哈希函數(shù),才可以使在各個(gè)reduce任務(wù)時(shí)負(fù)載勻衡)。詳細(xì)可以查看MapTask類。N個(gè)輸入可以產(chǎn)生M個(gè)map任務(wù)去跑,每個(gè)map任務(wù)會(huì)產(chǎn)生配置的reduce任務(wù)數(shù)個(gè)輸出文件。每個(gè)輸出文件都會(huì)面向一個(gè)特定的reduce任務(wù)同時(shí)所有從map任務(wù)產(chǎn)生的鍵值對(duì)都會(huì)被送到reduce里。所以在一個(gè)特定的reduce任務(wù)中對(duì)于一個(gè)給定的key所有的鍵值對(duì)都會(huì)被處理。
1.2 Combine(本地reduce)
當(dāng)map操作輸出它的鍵值對(duì)時(shí)他們已經(jīng)在內(nèi)存中存在了。為了性能和效率的考慮,有時(shí)候提供一個(gè)擁有reduce功能的合成器是有好處的。如果有合成器,那么map的鍵值對(duì)就不會(huì)被馬上寫入到輸出里,他們會(huì)被收集在list里,一個(gè)key值一個(gè)list,當(dāng)寫入一定數(shù)量的鍵值對(duì)時(shí),這部分緩沖會(huì)被送進(jìn)合成器,每個(gè)key都的所有value都會(huì)被送進(jìn)合成器的reduce方法里并且就像原先map輸出的鍵值對(duì)一樣。?比如,hadoop案例中的wordcount程序,它的map操作輸出是(word,1)鍵值對(duì),在輸入中的詞的計(jì)數(shù)可以用合成器來加速這個(gè)操作。一個(gè)合成操作會(huì)在內(nèi)存中收集處理lists,一個(gè)詞一個(gè)list。當(dāng)一定數(shù)量的鍵值對(duì)輸出到內(nèi)存中時(shí),就調(diào)用合成操作的reduce方法,每次都以一個(gè)唯一的詞為key,values是list的迭代器。然后合成器輸出(word,count-in-this-part-of-the-input)鍵值對(duì)。從Reduce操作的觀點(diǎn)來說合成器也擁有Map輸出中相同的信息,但是這樣會(huì)比原先遠(yuǎn)遠(yuǎn)減少硬盤的讀寫。
2. Reduce
?當(dāng)一個(gè)reduce任務(wù)開始時(shí),它的輸入是分散在各個(gè)節(jié)點(diǎn)上的map的輸出文件里。如果在分布式的模式下,他們需要先在拷貝步驟里拷貝到本地文件系統(tǒng)上。詳細(xì)可以查看ReduceTaskRunner類一旦所有的數(shù)據(jù)都在本地有效時(shí),它會(huì)在添加步驟里加到一個(gè)文件里。然后這個(gè)文件會(huì)被合并分類這樣相同的key的鍵值對(duì)就可以排在一起(分類步驟)。這樣可以使真正的reduce操作變得簡(jiǎn)單,這個(gè)文件會(huì)被順序地讀入,值(values)會(huì)從輸入文件里用一個(gè)迭代器傳給reduce方法-直到下一個(gè)key。詳細(xì)可以查看ReduceTask類。
?最后,輸出由每個(gè)reduce任務(wù)的輸出文件組成。面他們的格式可以由JobConf.setOutputFormat類指定,如果用到JobConf.setOutputFormat類,那么輸出的key類和value類都要同時(shí)指定。
3. 舉例子:
我們以wordcount為例,假設(shè)有個(gè)6400M的文件,100臺(tái)hadoop機(jī)器(準(zhǔn)確地說應(yīng)該是tasktracker機(jī)),默認(rèn)block大小為64M,這樣每臺(tái)執(zhí)行map的文件剛好是一個(gè)64M的block文件(假設(shè)這個(gè)分發(fā)過程已經(jīng)完成,同時(shí)忽略備份數(shù)之類的細(xì)節(jié)),并且我們使用10個(gè)reduce任務(wù)來歸并文件。Hadoop的mapreducer的執(zhí)行過程如下:
這100臺(tái)機(jī)器上面的map都是并發(fā)、獨(dú)立的執(zhí)行,以wordcount為例,步驟如下:
1、 每個(gè)map任務(wù)使用默認(rèn)的textinputformat類的LineRecordReader方法按行讀取文件,這個(gè)讀取的行數(shù)據(jù)就被交給map函數(shù)去執(zhí)行,wordcount的map做的就是提取里面的單詞,并以單詞為key,1為value作為輸出,格式為:<wordinteger(1)>。
2、 如果有combine,先對(duì)第一步的輸出結(jié)果就行combine操作。Combine就是個(gè)小reduce操作,作用就是對(duì)某個(gè)map自己的輸出結(jié)果先進(jìn)行一次歸并,把相同word的計(jì)數(shù)累加,這樣假設(shè)某個(gè)map輸出結(jié)果做如果有50%的重復(fù)word,那combine后的中間結(jié)果大小可以減少一半,可減少后續(xù)的patition、copy、sort等的開銷,提高性能。
3、 每個(gè)map對(duì)自己的輸出文件進(jìn)行patition操作。上面提到有10個(gè)reducer任務(wù),那默認(rèn)的patition操作就是對(duì)map的輸出kay進(jìn)行hash,并對(duì)10求余(hash(key)),并提供10個(gè)文件(內(nèi)存足夠的話可以是鏈表等內(nèi)存數(shù)據(jù)結(jié)構(gòu)),假設(shè)是r1、r2….r10這10個(gè)文件,把不同key的放到不同的文件,這次操作就可以把相同key聚合到同一個(gè)文件。由于算法一樣,保證了每個(gè)map的輸出結(jié)果經(jīng)過這個(gè)操作后,相同key的肯定在同一個(gè)聚合文件里,比如某個(gè)單詞word肯定都在r1文件里。
4、 接下來就是copy文件的過程了,10個(gè)reducer任務(wù)各自從所有map機(jī)器上取到屬于自己的文件,比如reducer1會(huì)從100臺(tái)map機(jī)器上取到所有r1文件,reducer2取所有r2的文件,這樣同一類word已經(jīng)到了同一臺(tái)reducer機(jī)器上了。
5、 每個(gè)reducer合并(meger)自己取到的文件,reducer1就是合并100個(gè)r1文件(實(shí)際過程是在上面第4步操作中會(huì)邊copy邊meger,在內(nèi)存中)。
6、 合并好后進(jìn)行下sort(排序)操作,再次把不同小文件中的同一個(gè)單詞聚合在一起。作為提供給reduce操作的數(shù)據(jù)。
7、 進(jìn)行reduce操作,對(duì)同一個(gè)單詞的value列表再次進(jìn)行累加,最終得到某個(gè)單詞的詞頻數(shù)。
8、 Outputformat操作,把reduce結(jié)果寫到磁盤。
所以,總的流程應(yīng)該是這樣的:
* ?Inputformat——》map——》(combine)——》partition——》copy&merge——》sort——》reduce——》outputformat
由此我們也可以看出,執(zhí)行reduce的代價(jià)還是有些的,所以如果我們的應(yīng)用只使用map就能搞定的話,那就盡量不要再有reduce操作在其中。
總結(jié)
以上是生活随笔為你收集整理的map-reduce的八个流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis作为hibernate的二级缓
- 下一篇: HBase 0.94.21 zookee