Map Hadoop映射输出IOException在将配置中定义的类的子类作为输出发出时
我有3个简单的课程:Map Hadoop映射输出IOException在将配置中定义的类的子类作为输出发出时,map,hadoop,subclass,ioexception,Map,Hadoop,Subclass,Ioexception,我有3个简单的课程: public abstract class Container implements WritableComparable<Container> {} //empty public class WeightedEdge extends Container { ... } public class NodeWeightContainer extends Container { ... } 但是,我收到此错误: java.io.IOException: Type
public abstract class Container implements WritableComparable<Container> {} //empty
public class WeightedEdge extends Container { ... }
public class NodeWeightContainer extends Container { ... }
但是,我收到此错误:
java.io.IOException: Type mismatch in value from map: expected org.hadoop.test.data.util.Container, recieved org.hadoop.test.data.WeightedEdge
at org.apache.hadoop.mapred.MapTask$MapOutputBuffer.collect(MapTask.java:1018)
at org.apache.hadoop.mapred.MapTask$OldOutputCollector.collect(MapTask.java:591)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:33)
at org.hadoop.test.map.CreateGPMap.map(CreateGPMap.java:19)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:50)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:435)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:371)
at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)
为什么我不能返回配置中定义的类的子类?有办法绕过它吗?问题是我的映射阶段必须发出两种不同的对象类型。您不能返回在配置中定义的类的子类,因为Hadoop显式检查在
setMapOutputValueClass
中指定的类类型以及它从映射器接收的类型
这样做是因为它需要序列化/反序列化从映射器发出的对象。当执行反序列化时,它将创建在setMapOutputValueClass
调用中指定的类型的新对象,然后使用WriteableComparable接口的方法用数据填充新创建的对象
为了能够发出不同的对象类型,您可以定义容器非抽象类,并将实际对象及其类型标识符放在其中
public enum ELEM_TYPE { WE, WECONTAINER }
public class Container implements WritableComparable<Container>
{
ELEM_TYPE type; //actual element type -
// WeightedEdge or NodeWeightContainer
object value;
//WritableComparable implementation
// that casts value to the appropriate type
}
public class WeightedEdge { ... }
public class NodeWeightContainer { ... }
公共枚举元素类型{WE,WECONTAINER}
公共类容器实现了WritableComparable
{
元素类型;//实际元素类型-
//权重边或节点权重容器
目标价值;
//可写可比实现
//将值强制转换为适当的类型
}
公共类权重边沿{…}
公共类NodeWightContainer{…}
无法返回配置中定义的类的子类,因为Hadoop会显式检查在setMapOutputValueClass
中指定的类类型及其从映射程序接收的类型
这样做是因为它需要序列化/反序列化从映射器发出的对象。当执行反序列化时,它将创建在setMapOutputValueClass
调用中指定的类型的新对象,然后使用WriteableComparable接口的方法用数据填充新创建的对象
为了能够发出不同的对象类型,您可以定义容器非抽象类,并将实际对象及其类型标识符放在其中
public enum ELEM_TYPE { WE, WECONTAINER }
public class Container implements WritableComparable<Container>
{
ELEM_TYPE type; //actual element type -
// WeightedEdge or NodeWeightContainer
object value;
//WritableComparable implementation
// that casts value to the appropriate type
}
public class WeightedEdge { ... }
public class NodeWeightContainer { ... }
公共枚举元素类型{WE,WECONTAINER}
公共类容器实现了WritableComparable
{
元素类型;//实际元素类型-
//权重边或节点权重容器
目标价值;
//可写可比实现
//将值强制转换为适当的类型
}
公共类权重边沿{…}
公共类NodeWightContainer{…}
我今天也遇到了同样的问题。有一个writeable
类org.apache.hadoop.io.genericwriteable
,可以用来解决这个问题。您需要扩展该类并实现一个抽象方法:
public class Container extends GenericWritable {
private static Class[] CLASSES = {
WeightedEdge.class,
NodeWeightContainer.class,
};
protected Class[] getTypes() {
return CLASSES;
}
}
public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
现在可以使用类容器作为映射器的输出值类型
重要提示:您的实际地图输出类(WeightedEdge
和nodeweightcainer
)必须实现可写
接口。我今天也遇到了同样的问题。有一个writeable
类org.apache.hadoop.io.genericwriteable
,可以用来解决这个问题。您需要扩展该类并实现一个抽象方法:
public class Container extends GenericWritable {
private static Class[] CLASSES = {
WeightedEdge.class,
NodeWeightContainer.class,
};
protected Class[] getTypes() {
return CLASSES;
}
}
public class WeightedEdge implemets Writable {...}
public class NodeWeightContainer implements Writable {...}
现在可以使用类容器作为映射器的输出值类型
重要提示:实际地图输出类(WeightedEdge
和nodeweightcainer
)必须实现可写
接口