Mapreduce自定义输入输出组件的认识

时间:2023-01-27 09:57:42

在进行Mapreduce的计算中,经常有需要按照自己的要求输入输出各种格式的需求。因此在这里,我简单将我了解的关于Mapreduce中自定义输入输出格式的认识分享给大家。

首先,我们从输出格式开始说,这个比较简单。Mapreduce的输出格式的主要切入点是最后的context.write(key,value)方法。需要定义自己的输出格式,就必须改下这个write方法,让他按照我们自己的要求输出。通过查看源码,我们会发现reduce中的write方法,其实是reducer中的run方法的一个while循环控制的。只要还有下一个key就调用reduce的write方法,输出内容。因此,我们翻阅源码可以发现context.write(key,value),等于reduceContext.write(key,value),等于TaskInputOutputContextImpl.write(key,value),z等于ReduceContextImpl的构造方法中的write(key,value),等于TextOutputFormat对象中的getRecordWriter中返回的write方法。因此,我们通过一层层的翻源码发现,要修改输出格式,只需要自定义outputFormat类,并重写RecordWrite类中的write方法。好了,下面我们来个例子说明怎么定义outputFormat类,并修改RecordWriter类中的write方法。

我们定义自己的MyOutputFormat类,实现FileOutputFormat,传入参数类型为我们根据业务逻辑定义的需要输出的类型。

public class MyOutputFormat extends FileOutputFormat<Text, NullWritable> {
@Override
public RecordWriter<Text, NullWritable> getRecordWriter(TaskAttemptContext job)
throws IOException, InterruptedException {
Configuration configuration = job.getConfiguration();
FileSystem fileSystem = FileSystem.get(configuration);
return new MyRecordWriter(fileSystem);
}
}

该类需要返回一个RecordWriter的对象,该对象中的wirte方法,使我们修改的关键地方。因此我们在这里需要返回一个自己定义的RecordWrite类.

这里,我将要定义的类命名为MyRecordWriter。另起一个java文件,重新定义MyRecordWriter类,并重写其方法,重点修改write方法。

public void write(Text key, NullWritable value) throws IOException, InterruptedException {
String[] split = key.toString().split(",");
if(Integer.parseInt(split[0])==1){
outputPath1.write(key.toString().getBytes());
outputPath1.write("\n".getBytes());
}else{
outputPath2.write(key.toString().getBytes());
outputPath2.write("\n".getBytes());
}

}

MyRecordWriter类中主要重写write方法和close方法,close方法就是用来关闭自定义的流的。write方法则为我们编写输出格式的地方。在我的例子中,我根据自己的需要,将输出文件,按照第一个字符是不是为1,分为了两个文件输出。-----超级简单的测试,这里可以根据业务逻辑需要,随意更改。

注意,例子中我的输出路径,是通过MyOutputFormat中传过来的fileSystem对象的create()创建的输出路径,由于write方法中并没有fileSystem对象,因此需要将该对象设置为成员变量,共享给write方法。

最后,搞定了outputFormat的输出格式,我们需要在main方法中,通过job.setOutputFormatClass(MyOutputFormat.class)告诉框架,我们使用了自己定义的输出格式。

mapreduce程序中的逻辑部分不需要任何的改变,我们的输出就能根据自己的需求输出啦。

(输入组件的认识稍后更新)

赶紧试试新招,让自己的程序活起来吧!