Mapreduce编程:需要详细信息

时间:2014-04-18 10:33:35

标签: java hadoop map mapreduce reduce

我需要一些帮助来理解mapreduce流程,而不是理论上,而是参考普通的Java代码片段。我一直在阅读关于hadoop处理的教程,API,论坛和其他主题相关事宜; mapreduce。我对流动,hadoop的处理方法非常满意。我理解的问题与Java中的mapreduce编码有关。我已经阅读并尝试了一些已有的代码;即,wordcount等。我无法理解的是原始数据流入Mapper& Reducer类(严格按照Java代码而不是理论流程)。

我也尝试用代码表示它;也许我可以让自己更容易理解。让我们来说一下经典的wordcount程序;地图宣言&减少我发现的地方:

public static class Map extends MapReduceBase implements 
    Mapper<LongWritable, Text, Text, IntWritable>

public static class Reduce extends MapReduceBase implements 
    Reducer<Text, IntWritable, Text, IntWritable>

我对上述代码段的查询:

  • 我如何决定所有4个参数&#39;类型应该在这里?
  • API定义表明它类似

    org.apache.hadoop.mapreduce.Mapper(KEYIN,VALUEIN,KEYOUT,VALUEOUT)

  • 如果我通过命令行将文件传递给我的程序,那么 论证全部内容如何?根据hadoop的理解 流程,我说前两个论点,即KEYIN&amp; VALUEIN将是 用过的。键将是单词,而值将在那里计数(无论地图阶段的输出是什么)。

  • 如何声明我的密钥是否应该是LongWritable。如果我 声明只有Integer类型的第一个参数? (我不是在谈论 整数与差异的区别LongWritable类型,但基本 决定)。
  • 我如何确定问题的哪一部分应该在我的映射器中 class和reducer类应该是什么部分?
  • 声明的参数类型是否应该在mapper&amp;减速机类是 相同或不同?与上述声明一样​​,它们也不同。这算怎么算?我能想到的唯一答案是地图阶段输出中间值,这些中间值可能与地图类的输入类型不同。 (对此不确定,如果荒谬,请原谅这个解释。)

例如,我尝试编写一个小代码,用逗号分隔的整数值找出小文本文件中的最大数字。首先,我无法决定在哪里进行处理;在mapper类或reducer类中?看看周围的众多代码,我以某种方式得出结论,处理应该在reducer类中,而我可以在mapper类中应用一些基本检查到我的输入。这个逻辑我只是自己承担,所以你可以在这上面玩得开心:) 有人可以告诉我这段代码中的错误吗?可能会帮助我清除我的理解吗?

我的代码:

public class mapTest {
    public static class Map extends MapReduceBase implements 
    Mapper<Text, Text, Text, Reporter>{

        @Override
        public void map(Text text, Text value,
                OutputCollector<Text, Reporter> output, Reporter arg0)
                throws IOException {
            // TODO Auto-generated method stub
            String val = value.toString();

            if(val.equals(null)){
                System.out.println("NULL value found");
            }
            output.collect(value, arg0);

        }

    }

    public static class Reduce extends MapReduceBase implements
    Reducer<Text, Text, Text, Reporter>{

        public void reduce(Text key, Iterator<Text> value,OutputCollector<Text, Reporter> output, Reporter arg0)
                throws IOException {
            // TODO Auto-generated method stub
            Text max = value.next();

            while(value.hasNext()){
                Text current = value.next();
                if(current.compareTo(max) > 0)
                    max = current;
            }
            output.collect(key, (Reporter) max);
        }

    }



    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub

        JobConf conf = new JobConf();

        conf.setMapperClass(Map.class);
        conf.setReducerClass(Reduce.class);
        conf.setOutputKeyClass(Text.class);
        conf.setOutputValueClass(Text.class);
        conf.setInputFormat(TextInputFormat.class);
        conf.setOutputFormat(TextOutputFormat.class);
        FileInputFormat.setInputPaths(conf, new Path(args[0]));
        FileOutputFormat.setOutputPath(conf, new Path(args[1]));

        JobClient.runJob(conf);
    }

}

PS:参数类型,我只是随机提到虽然我不了解除Reporter类型之外的任何重要性。

在发布这个问题之前,我做了所有可能的研究。请帮我理解这个流程。我不想通过从其他地方拿起代码和做化妆品来弄乱一切。

提前致谢 -

阿迪尔

1 个答案:

答案 0 :(得分:0)

  • 映射器的KEYIN,VALUEIN和reducer的KEYOUT,VALUEOUT分别取决于您的输入/输出格式。映射输出k / v对必须与reducer的输入匹配。
  • 对于文本文件,您可能需要TextInputFormat。关键是文件的字节偏移量,值是行。从那里你可以解析你想要的任何数据,就像普通字符串一样。
  • LongWritable vs IntWritable就像选择int vs long一样。这一切都取决于您的数据。
  • 是否应该在mapper或reducer中完成大部分工作是有争议的。您通常使用比reducer更多的映射器,因此您可以利用更多的并行性。您还可以减少需要改组的数据量。在减少之前排序。然而,减速器具有基于键的所有值并置,因此处理也可能有意义。就个人而言,我尽可能地尽量减少数据。当一切都适合记忆时,Mapreduce是最有效的。