【hadoop蜜汁问题解决】Multioutputs按照key输出多个文件

本文记录了一位开发者在使用Hadoop MapReduce时遇到的关于MultiOutputs按照key输出多个文件的难题。在尝试百度无果后,作者深入源代码寻找答案。在1.2.1版本的Hadoop环境中,遇到map阶段溢出和reduce阶段无法打开文件的错误。最终解决方案是在map阶段使用MultiOutputs.write,而非reduce阶段,同时发现MultiOutputs.addNameOutput()并未起到预期效果。
摘要由CSDN通过智能技术生成

每当碰到一个很久都没有解决的bug时,总是开始怀疑人生,而且还各种百度不到,那就更加痛不欲生,尤其是这种大项目,看源代码太累了。

所以一旦解决了,一定要趁热乎的时候赶紧记录下来,不管用的是哪种谜一样的方法,好的,进入正题。

简而言之,我是想让mapreduce输出多个文件,按照key来输出文件,百度一下就可以发现很多说利用multioutputs类就可以解决,有些给了一点代码,不过很多都不靠谱,这个时候看源代码就很好了,或者去官网看.

(不放点代码就没有人看呀!!)

Job job = new Job();
 *
 * FileInputFormat.setInputPath(job, inDir);
 * FileOutputFormat.setOutputPath(job, outDir);
 *
 * job.setMapperClass(MOMap.class);
 * job.setReducerClass(MOReduce.class);
 * ...
 *
 * // Defines additional single text based output 'text' for the job
 * MultipleOutputs.addNamedOutput(job, "text", TextOutputFormat.class,
 * LongWritable.class, Text.class);
 *
 * // Defines additional sequence-file based output 'sequence' for the job
 * MultipleOutputs.addNamedOutput(job, "seq",
 *   SequenceFileOutputFormat.class,
 *   LongWritable.class, Text.class);
 * ...
 *
 * job.waitForCompletion(true);
 * ...
 * </pre>
 * <p>
 * Usage in Reducer:
 * <pre>
 * <K, V> String generateFileName(K k, V v) {
 *   return k.toString() + "_" + v.toString();
 * }
 * 
 * public class MOReduce extends
 *   Reducer<WritableComparable, Writable,WritableComparable, Writable> {
 * private MultipleOutputs mos;
 * public void setup(Context context) {
 * ...
 * mos = new MultipleOutputs(context);
 * }
 *
 * public void reduce(WritableComparable key, Iterator<Writable> values,
 * Context context)
 * throws IOException {
 * ...
 * mos.write("text", , key, new Text("Hello"));
 * mos.write("seq", LongWritable(1), new Text("Bye"), "seq_a");
 * mos.write("seq", LongWritable(2), key, new Text("Chau"), "seq_b");
 * mos.write(key, new Text("value"), generateFileName(key, new Text("value")));
 * ...
 * }
 *
 * public void cleanup(Context) throws IOException {
 * mos.close();
 * ...
 * }
上面是是从hadoop1.2.1/src\mapred\org\apache\hadoop\mapreduce\lib\output的Multioutputs.class文件中拷贝出来的,当然有些些微的错误,认真阅读一下懂怎么写啦,给大家一点发挥空间。


我正常使用也没有错误,接着就让我崩溃了。说一下我的环境吧:

hadoop版本1.2.1 ,使用虚拟机搭建集群,用伪分布式跑hadoop,eclipse连接hadoop进行开发,怎么连接参考我之前的博客。

当我在reduce中使用mos.write时,如果输入文件大于2M,就说fail to create file以及spill failed,说map阶段溢出,reduce阶段打不开文件,这令人费解,难道是什么大小设置得不对,找半天都找不到,并且我没有Multioutput.addnameoutput,反正我就各种怀疑人生,然后没找出原因,然后不断试。


最后不再reduce中mos.write了,直接在map中mos.write,然后就好了,并且我发现Multioutput.addnameoutput()没有什么用呀,最后还是

<span style="color:#FF0000;">mos.write("seq", LongWritable(1), new Text("Bye"), "seq_a");
最后一个参数决定文件名,如果文件名中有/还会生成文件夹,应该和linux的文件结构一样。反正也是醉了,最后解决了就是。</span>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值