第一步: MultipleOutputs.addNamedOutput()
main或run方法中注册,其中namedOutput为别名,不能是中文,不能包含下划线_ MultipleOutputs.addNamedOutput(Job job, String namedOutput, Class<? extends OutputFormat> outputFormatClass, Class<?> keyClass, Class<?> valueClass);
String dirName[] = acts.split(Constant.MARK_AITE);
for (String a : dirName) {
MultipleOutputs.addNamedOutput(job, a, TextOutputFormat.class,
NullWritable.class, Text.class);
}
logger.info("---excuter---");
***插播 详细介绍一下 MultipleOutputs.addNamedOutput(job, a, TextOutputFormat.class,
NullWritable.class, Text.class)
第二步:
然后就可以用mos.write(Key key,Value value,String baseOutputPath)代替context.write(key, value);
注意:multipleOutputs.write(key, value, baseOutputPath)方法的第三个函数表明了该输出所在的目录(相对于用户指定的输出目录)。 如果baseOutputPath不包含文件分隔符“/”,那么输出的文件格式为baseOutputPath-r-nnnnn(name-r-nnnnn); 如果包含文件分隔符“/”,例如baseOutputPath=“029070-99999/1901/part”,那么输出文件则为029070-99999/1901/part-r-nnnnn
public static class AutoActLogParseReducer extends Reducer<Text, Text, NullWritable, Text> {
private MultipleOutputs<NullWritable, Text> mos; // 输出类型和Reduce一致
@Override
protected void setup(Reducer<Text, Text, NullWritable, Text>.Context context)
throws IOException, InterruptedException {
mos = new MultipleOutputs<NullWritable, Text>(context);
}
@Override
protected void cleanup(
Reducer<Text, Text, NullWritable, Text>.Context context)
throws IOException, InterruptedException {
mos.close();
}
@Override
public void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
Text valText = new Text();
Text keyValue = new Text();
Iterator<Text> it = values.iterator();
String keyStr = key.toString();
while (it.hasNext()) {
String[] uk = it.next().toString().split(Constant.MARK_LINE);
for (String tmpUk : uk) {
valText.set(tmpUk);
mos.write(keyStr, NullWritable.get(), valText, keyStr + "/");
}
}
}
}