最近跑一個(gè)Hadoop程序,處理一年的log,處理的時(shí)候發(fā)現(xiàn)Map有18000多個(gè),Reduce任務(wù)數(shù)我設(shè)置了1000個(gè)。
最后半個(gè)小時(shí)過去了,所有Map都執(zhí)行完畢,就有一個(gè)Reduce沒有結(jié)束,然后沒管他繼續(xù)干其他的了。
兩個(gè)小時(shí)過去了,這個(gè)Reduce一開還是處于copy階段,進(jìn)度10%,受不了,直接kill掉,看日志,沒有問題啊,5個(gè)fetch都正常,就是網(wǎng)絡(luò)好慢。以為是數(shù)據(jù)量太大了,Reduce數(shù)太小了,最后取了一個(gè)月的數(shù)據(jù),1000個(gè)reduce,還是一樣。
最后定位到網(wǎng)絡(luò),明明自己的網(wǎng)絡(luò)很快,顯示的卻是1M/s,每次取那么點(diǎn)數(shù)據(jù)?分析程序,發(fā)現(xiàn)Combiner這個(gè)類被我不小心注釋掉了
job.setCombinerClass(MyReducer.class);
combiner就是在map輸出階段,小范圍的執(zhí)行“Reduce任務(wù)”,沒有加上,所以Reduce任務(wù)在copy階段copy的“碎片”比較多
其次,由于我處理Reduce結(jié)果輸出的編碼,所以在設(shè)置combiner類的時(shí)候,不能直接用Reduce類,稍微改一下,將combiner繼承Reduce類,但是在combiner中不要轉(zhuǎn)碼
public class MyCombiner extends Reducer<Text, LongWritable, Text, LongWritable> {
private LongWritable result = new LongWritable();
public void reduce(Text key, Iterable<LongWritable> values,Context context) throws IOException, InterruptedException {
long sum = 0;
for (LongWritable val : values) {
sum += val.get();
}
result.set(sum);
// context.write(new Text(key.toString().getBytes("GB18030")), result);//Reduce中這樣寫
context.write(key, result);
}
}