两个Mapper初始化输出类错误的心得:Unable to initialize any output collector

来源:互联网 发布:南风捏脸数据网盘 编辑:程序博客网 时间:2024/06/07 06:22

今天在跑两个关系运算的代码,结果接连两次都出现了同样的一个错误:

Error: java.io.IOException: Unable to initialize any output collectorat org.apache.hadoop.mapred.MapTask.createSortingCollector(MapTask.java:412)at org.apache.hadoop.mapred.MapTask.access$100(MapTask.java:81)at org.apache.hadoop.mapred.MapTask$NewOutputCollector.<init>(MapTask.java:695)at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:767)at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:163)at java.security.AccessController.doPrivileged(Native Method)at javax.security.auth.Subject.doAs(Subject.java:415)at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1628)at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)

错误都是出现在Mapper的task里面。错误说明输出的类型错误。百度了一把,发现有人提出这个问题,但是没有回答。


第一次出现的时候,通过查Job的代码,发现在setMapOutputKeyFormat方法里面,设定的输出是Text类型。但是在import里面却不是import的org.apache.hadoop.io.Text类,而是另外一个不知所云的包下面的Text。在修改成hadoop的Text类后,问题解决。


第二次出现就很奇葩了。写了一个RelationAlgebra的MapReduce类。其中Mapper的输出是自己写的一个Key类,而不是hadoop.io里面的已有的类,比如Text,LongWritable等等。在运行的时候有出现了 Unable to initialize any output collector的IOException。仔细检查了自己写的Mapper,Reducer和主Job程序,死活找不到问题出现在哪里。

这个输出的Key类是实现了WritableCompareble接口,其中的readField和write方法都没问题,compareTo也反复检查,自己写的hashCode方法也调测多遍。但是问题依旧。


无奈网上搜各种跟自己写Key类相关的帖子。终于在一个介绍自定义Key类的帖子里面发现了线索。链接http://blog.csdn.net/lastsweetop/article/details/9360075

在这个帖子里面有一句话,

    /**      * 必须有默认的构造器皿,这样Mapreduce方法才能创建对象,然后通过readFields方法从序列化的数据流中读出进行赋值      */      public EmploeeWritable() {          set(new Text(),new Text());      } 

回头检查自己写的Key类,发现并没有显式地定义这个构造函数。在添加了无参数的构造函数后,问题解决。


在Hadoop 2.6.0的API文档中,对于WritableCompareble的介绍并没有特别指出这个要求。不知道是因为这个要求在以前的版本里面已经众所周知了,还是API作者忽视了。对于开始学习MapReduce编程的人来说,这个还是挺困惑的,因为log给出的错误几乎没有参考价值。


2 0
原创粉丝点击