/ 中存储网

MapReduce中多文件输出的使用的两种方法总结

2015-07-17 22:59:11 来源:中存储网

在Mapreduce 的程序设计中,有时候会遇到多文件输出的使用。job 定义的FileOutputFormat 默认只有一个输出,如果是多机实现,该目录下包含多个类似part-000xx 的文件。在mapreduce中一个reducer对一个recordwriter,recordwriter只负责最后数据的写入,因此文件的个数与job指定的reduce个数一致。
但是我们需要多文件输出怎么处理,目前总结为两种方法:

第一种方法:使用MultipleOutputFormat
MultipleOutputFormat 只是一个抽象的类,MultipleTextOutputFormat 和MultpleSequenceFileOutputFormat 是它的两个具体实现。顾名思义,MultipleTextOutputFormat 的多个文件输出都是TextOutputFormat,即一行一对的文本格式,而MultpleSequenceFileOutputFormat 的多个文件输出都是SequenceFile,即二进制文件格式。
具体实现方法如下:
实现方式可以直接继承MultipleOutputFormat 抽象累,也可直接继承MultipleTextOutputFormat类重写generateFileNameForKeyValue方法,如果输出文件为二进制格式则直接继承MultpleSequenceFileOutputFormat 类。我这里输出为text格式,所以直接继承MultipleTextOutputFormat类,代码如下:

  1.         static class MyMultipleOutputFormat extends MultipleTextOutputFormat<Text, Text>{
  2.                 
  3.                 @Override
  4.                 protected String generateFileNameForKeyValue(Text key,Text value,String name){
  5.                         // 相同key值的放在同一个文件夹下
  6.                         return new Path(key.toString(), name).toString();
  7.                         
  8.                 }

最后在jobconfig中配置输出格式:

  1. JobConf job = new JobConf();
  2.                 // 设置输出格式。
  3.                 job.setOutputFormat(MyMultipleOutputFormat.class);

这种方式实现其实是通过实现输出文件指定目录,如果直接按照key输出在同一个文件,则generateFileNameForKeyValue 返回值直接修改为return key。

第二种方式:使用MultipleOutputs
MultipleOutputs 是在job 指定的output 输出的基础上,新增加一些额外的输出,与MulitpleOutputFormat 相比,它才是真正意义上的多文件输出。分两种情况:
附加单个输出文件,调用MultipleOutputs 的addNamedOutput 方法, 则是添加一个附加文件OutputFormat 格式及key, value 类型都可以自定义;代码实现如下:

  1. JobConf job = new JobConf();
  2.                 
  3.                 MultipleOutputs.addNamedOutput(job, "myfile", TextOutputFormat.class, NullWritable.class, Text.class);

另一种方式是多个文件输出,在reduce阶段增加一些输出:

  1. <blockquote>public static class Reduce extends Reducer<Text,Text,Text,Text>{