多种自定义可写格式

时间:2012-04-24 09:10:05

标签: hadoop writable

我有多个输入源,我使用Sqoop的codegen工具为每个输入源生成自定义类

public class SQOOP_REC1 extends SqoopRecord  implements DBWritable, Writable

public class SQOOP_REC2 extends SqoopRecord  implements DBWritable, Writable

在Map侧,基于输入源,我相应地创建了上述2个类的对象。

我将密钥作为“Text”类型,因为我有2种不同类型的值,所以我将值输出类型保持为“可写”。

在reduce方面,我接受值类型为Writable。

   public class SkeletonReduce extends Reducer<Text,Writable, Text, Text> {

public void reduce(Text key, Iterable<Writable> values, Context context) throws     IOException,InterruptedException {

   }
}

我也设置了

job.setMapOutputValueClass(Writable.class);

在执行期间,它根本不会进入reduce函数。

有人可以告诉我是否可以这样做?如果是这样,我做错了什么?

3 个答案:

答案 0 :(得分:0)

您不能指定Writable作为输出类型;它必须是具体的类型。所有记录都需要在MapperReducer中具有相同(具体)的键和值类型。如果您需要不同的类型,您可以创建某种混合Writable,其中包含“A”或“B”。它有点难看,但有效,并且在Mahout中做了很多。例如。

但我不知道为什么这会导致减速器无法运行;根据这些信息,这可能是相当独立的,并且无法回答。

答案 1 :(得分:0)

考虑为您的值类型扩展GenericWritable。您需要定义允许的类集(在您的情况下为SQOOP_REC1和SQOOP_REC2),并且它不那么有效,因为它在readFields方法中创建了新的对象实例(但如果您有一小组类,则可以覆盖它,只有两种类型的实例变量,以及一个表示哪一个有效的标志)

答案 2 :(得分:0)

好的,我想我想出了如何做到这一点。根据Doug Cutting自己提出的建议

http://grokbase.com/t/hadoop/common-user/083gzhd6zd/multiple-output-value-classes

我使用ObjectWritable

包装了这个类
ObjectWritable obj = new ObjectWritable(SQOOP_REC2.class,sqoop_rec2);

然后在Reduce方面,我可以获取包装类的名称并将其转换回原始类。

if(val.getDeclaredClass().getName().equals("SQOOP_REC2")){
                SQOOP_REC2temp = (SQOOP_REC2) val.get();

别忘了

        job.setMapOutputValueClass(ObjectWritable.class);