//将所有不正常的记录都保存到最后一个分区中
public static class ErrorPartitioner implements Partitioner<Text, Text> { @Override public void configure(JobConf conf) { } @Override public int getPartition(Text key, Text value, int numPartitions) { if (key.toString().startsWith("error")) { //写到最后一个分区中 return numPartitions-1; } else { //对于正常的记录直接使用HashPartitioner来指定分区 return ((key.hashCode() & Integer.MAX_VALUE) % (numPartitions-1)); } } }
MultipleOutputs.addNamedOutput(conf, "Prefix1", TextOutputFormat.class, Text.class, IntWritable.class); MultipleOutputs.addNamedOutput(conf, "Prefix2", TextOutputFormat.class, Text.class, IntWritable.class); .............. JobClient.runJob(conf);
public static MultipleOutputs mos; public void configure(JobConf job) { mos = new MultipleOutputs(job); } 3、在map或者reduce方法中象下面这样使用之。 if (key.toString().length() < 3) { mos.getCollector(file1, reporter).collect( key, new IntWritable(sum)); } else { mos.getCollector(file2, reporter).collect( key, new IntWritable(sum)); }
4、最后一定记得实现Mapper和Reducer类的close方法,在该方法中调用"mos.close();",否则不会有数据写入到文件中。
生成的文件形如"Prefix1-m-00001",前缀自己可以设置。今天还学会判断记录所在的文件,有时候这个信息比较有用。一共有两种方法可以知道当前处理的记录所属的文件。
1、通过JobConf来获得。
public void configure(JobConf job) { path = job.get("map.input.file"); }
String path = ((FileSplit) reporter.getInputSplit()).getPath().toString();