mapreduce编程:需要详细信息

ercv8c1e  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(428)

我需要一些帮助来理解mapreduce流,不是理论上的,而是参考普通java代码片段。我一直在阅读关于hadoop处理的教程、api、论坛和其他主题相关的内容;MapReduce。我非常熟悉hadoop的流程和处理方法。我理解的问题与java中的mapreduce编码有关。我已经阅读并尝试了一些已经存在的代码;i、 我不能理解的是原始数据流入mapper和reducer类(严格地说是java代码,而不是理论流)。
我也会试着用代码来表达它;也许我可以这样让自己更容易理解。比如说经典的wordcount程序;我在某处找到的map&reduce类声明如下:

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个参数的类型?
API的定义是
org.apache.hadoop.mapreduce.mapper(keyin,valuein,keyout,valueout)
如果我通过命令行将文件传递给我的程序,那么整个内容将以什么参数传递?根据对hadoop流的理解,我将使用前两个参数,即keyin和valuein。键将是单词,而值将在那里计数(无论Map阶段的输出是什么)。
如何声明我的密钥是否应该是可长写的。如果我只声明integer类型的第一个参数呢(我说的不是integer和longwritable类型之间的区别,而是基本决定)。
我如何决定我的问题的哪一部分应该在我的mapper类中,哪一部分应该在reducer类中?
mapper&reducer类中声明的参数类型应该相同还是不同?就像上面的声明一样,它们是不同的。这算什么?我能猜到的唯一答案是map阶段输出的中间值可能与map类的输入类型不同(不确定,所以请原谅这个解释(如果荒谬的话)。
例如,我尝试编写一个小代码,用逗号分隔的整数值找出一个小文本文件中的最大数。首先,我不能决定在哪里进行处理;在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);
    }

}

附言:论点类型,我只是随便提到,虽然除了记者类型,我不明白其他类型的重要性。
在发布这个问题之前,我做了所有我能做的研究。请帮我理解这个流程。我不想把所有的事情都搞砸了,我只是从别的地方拿起密码,做化妆品。
提前谢谢-
阿迪尔

lp0sw83n

lp0sw83n1#

mapper的keyin、valuein和reducer的keyout、valueout分别取决于您的输入/输出格式。map输出k/v对必须与减速器的输入匹配。
对于文本文件,您可能需要textinputformat。键是文件的字节偏移量,值是行。从那里你可以像解析普通字符串一样解析出你想要的任何数据。
longwritable vs intwritable就像选择int vs long一样。这完全取决于你的数据。
大部分工作是应该在mapper还是reducer中完成,这有待商榷。通常使用的Map器比还原器多,因此可以利用更多的并行性。您还可以减少在减少数据量之前需要洗牌和排序的数据量。但是,reducer的所有值都是基于键配置的,因此处理在那里也是有意义的。就我个人而言,我尽可能早地尽量减少数据量。当所有的东西都能放在内存中时,mapreduce是最有效的。

相关问题