使用新API的Hadoop自定义输入格式

时间:2012-02-13 10:05:54

标签: hadoop mapreduce

我是Hadoop的新手,我遇到了以下问题。我想要做的是将数据库的碎片(请不要问我为什么需要这样做等)映射到映射器,然后对此数据执行某些操作,将结果输出到reducer并再次使用该输出使用相同的分片格式对相同数据执行第二阶段映射/减少作业。 Hadoop不提供任何输入方法来发送数据库的分片。您只能使用LineInputFormat和LineRecordReader逐行发送。在这种情况下,NLineInputFormat也没有帮助。我需要扩展FileInputFormat和RecordReader类来编写自己的InputFormat。我被建议使用LineRecordReader,因为底层代码已经处理了FileSplits以及与拆分文件相关的所有问题。 我现在需要做的就是覆盖nextKeyValue()方法,我不知道该怎么做。

   for(int i=0;i<shard_size;i++){
           if(lineRecordReader.nextKeyValue()){                               lineValue.append(lineRecordReader.getCurrentValue().getBytes(),0,lineRecordReader.getCurrentValue().getLength());

}

上面的代码片段是写的但不知何故不能正常工作的代码片段。先谢谢你

2 个答案:

答案 0 :(得分:0)

我建议将输入文件中的连接字符串和其他一些指示放在哪里找到分片。
Mapper将获取此信息,连接到数据库并完成工作。我不建议将结果集转换为hadoop的可写类 - 它会妨碍性能 我认为要解决的问题是这个相对较小的输入有足够的分裂。 您可以简单地创建足够的小文件,每个文件都有一些分片引用,或者您可以调整输入格式以构建小分割。第二种方式会更灵活。

答案 1 :(得分:0)

我做了什么,是这样的。我编写了自己的记录阅读器,一次读取n行,并将它们作为输入发送给映射器

public boolean nextKeyValue() throws IOException, 

InterruptedException {

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 5; i++) {
        if (!lineRecordReader.nextKeyValue()) {
            return false;
        }
        lineKey = lineRecordReader.getCurrentKey();
        lineValue = lineRecordReader.getCurrentValue();
        sb.append(lineValue.toString());
        sb.append(eol);
    }
    lineValue.set(sb.toString());
    //System.out.println(lineValue.toString());

    return true;

    // throw new UnsupportedOperationException("Not supported yet.");
} 

你怎么瘦?