在Oozie工作流中使用MultipleOutputs.addNamedOutput修改Reducer输出文件名遇阻
在Oozie MapReduce动作中配置MultipleOutputs
我刚好碰到过类似的场景,在Oozie里跑MapReduce又没法修改Driver代码的时候,确实得靠配置项来替代MultipleOutputs.addNamedOutput()的代码逻辑。下面给你具体的实现方法:
核心思路
Oozie的MapReduce动作允许通过<configuration>标签传递所有MapReduce作业的配置参数,而MultipleOutputs的命名输出完全可以通过这些配置项来定义,不需要编写Java Driver代码。
具体配置步骤
在你的Oozie workflow.xml的MapReduce动作里,添加以下配置:
<action name="mapreduce-job"> <map-reduce> <job-tracker>${jobTracker}</job-tracker> <name-node>${nameNode}</name-node> <configuration> <!-- 启用MultipleOutputs作为作业的输出格式 --> <property> <name>mapreduce.job.outputformat.class</name> <value>org.apache.hadoop.mapreduce.lib.output.MultipleOutputsFormat</value> </property> <!-- 定义命名输出的名称列表,这里是"text" --> <property> <name>mapreduce.multipleoutputs.namedOutputs</name> <value>text</value> </property> <!-- 配置"text"这个命名输出的输出格式,对应代码里的TextOutputFormat.class --> <property> <name>mapreduce.multipleoutputs.namedOutput.text.outputFormat</name> <value>org.apache.hadoop.mapreduce.lib.output.TextOutputFormat</value> </property> <!-- 配置"text"输出的Key类型,对应代码里的Text.class --> <property> <name>mapreduce.multipleoutputs.namedOutput.text.keyClass</name> <value>org.apache.hadoop.io.Text</value> </property> <!-- 配置"text"输出的Value类型,对应代码里的Text.class --> <property> <name>mapreduce.multipleoutputs.namedOutput.text.valueClass</name> <value>org.apache.hadoop.io.Text</value> </property> <!-- 其他你的MapReduce配置项 --> <property> <name>mapreduce.map.class</name> <value>your.package.YourMapper</value> </property> <property> <name>mapreduce.reduce.class</name> <value>your.package.YourReducer</value> </property> <property> <name>mapreduce.output.dir</name> <value>${outputDir}</value> </property> </configuration> </map-reduce> <ok to="next-action"/> <error to="fail"/> </action>
注意事项
- Hadoop版本兼容:如果你的集群用的是Hadoop 1.x,配置属性的前缀需要改成
mapred.而不是mapreduce.,比如mapred.multipleoutputs.namedOutputs。 - Reducer中的使用:在你的Reducer代码里,仍然可以正常使用MultipleOutputs的API来写入这个命名输出,比如:
@Override protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { MultipleOutputs mos = new MultipleOutputs(context); // 写入到"text"这个命名输出 mos.write("text", key, new Text("your-value")); mos.close(); } - 多命名输出:如果需要多个命名输出,只需要在
mapreduce.multipleoutputs.namedOutputs里用逗号分隔多个名称,然后为每个名称添加对应的outputFormat、keyClass、valueClass配置即可。
内容的提问来源于stack exchange,提问作者Charitra kocheri
相关产品推荐
相关产品推荐

