从0.20.0 版本开始,Hadoop 同时提供了新旧两套MapReduce API。部分早期的0.20发行版本反对使用旧的api,但是后续版本中可以继续使用旧的api,因此1.x和2.x发行版本同时支持就的api。
新旧API之间有如下几个明显区别:
- 新API倾向使用虚类,而不是接口,因为更有利扩展。
- 新API移到org.apache.hadoop.mapreduce包及其子包中,而旧的API放在org.apache.hadoop.mapred下。
- 新API充分使用上下文对象,使用户代码能在MapReduce系统通信。例如,新的Context基本统一了旧的API中的JobConf、OutputCollector和Reporter的功能。
- 键/值对记录在这两类API中都被推给了mapper和reducer,但除此之外,新的API通过重写run()方法允许mapper和reducer控制执行流程。
- 新API中作业控制由Job类实现,而旧的API中的JobClient类,新的API中删除了JobClient类。
- 新增的API实现了配置的统一。旧API通过一个特殊的JobConf对象配置作业,该对象是Hadoop配置对象的一个扩展。在新API中,作业的配置由Configuration类完成。
- 输出文件的命名方式稍有不同。在旧的API中map和reduce的输出被统一命名为part-nnmm,但是新的API中map的输出文件名为part-m-nnnn,而reduce的输出文件名为part-r-nnnnn(其中nnnnn是从0开始的表示分块序号的整数)。
- 新的API中用户冲在函数被声明为抛出异常java.lang.InterruputedException。这意味着可以用代码来实现中断响应,从而使该框架在必要时可以优雅的取消长时间运行的作业。
- 在新的API中,reduce()传递的值是java.lang.Iterable类型的,而非java.lang.Iterator类型,这一改变使我们可以更容易是欧诺更for-each循环来迭代这些值。
----------------Iterator迭代 ----------------------
public static class Reduce extends MapReduceBase implements Reducer<Text, LongWritable, Text, LongWritable>{
@Override
public void reduce(Text key, Iterator<LongWritable> values, OutputCollector<Text, LongWritable> output,
Reporter reporter) throws IOException {
long count = 0;
while(values.hasNext()){
count+=values.next().get();
}
output.collect(key, new LongWritable(count));
}
}
--------------Iterable for-each迭代---------------
public static class FriendListReducer extends Reducer<Text,Text,Text,Text>{
private Text friendsNames=new Text();
@Override
protected void reduce(Text key,
Iterable<Text> values,Context context) throws IOException, InterruptedException{
StringBuffer buffer=new StringBuffer();
for(Text name:values){
buffer.append(","+name);
}
friendsNames.set(buffer.toString());
context.write(key,friendsNames);
}
}