是否可以在一个节点上运行多个映射器

时间:2016-05-15 15:12:00

标签: java hadoop mapreduce

我有KMeans的代码,我的任务是计算加速,我通过在我的uni集群中的不同数量的节点上运行它来完成它。但是是否可以更改映射器和/或减速器的数量,以便在单节点上运行时可以检查加速的变化。

谷歌搜索时,我发现使用conf.setNumReduceTasks(2);我可以改变减速器的数量。但我看不出我的输出有任何变化。 (我的输出是以ms为单位的时间。)

我使用的代码来自github:https://github.com/himank/K-Means/blob/master/src/KMeans.java 虽然我已根据我的要求做了一些更改,但主要功能是相同的。

主要功能如下:

    public static void main(String[] args) throws Exception {
    long startTime = System.currentTimeMillis();
    IN = args[0];
    OUT = args[1];
    String input = IN;
    String output = OUT + System.nanoTime();
    String again_input = output;
    int iteration = 0;
    boolean isdone = false;
    while (isdone == false) {
        JobConf conf = new JobConf(KMeans.class);
        if (iteration == 0) {
            Path hdfsPath = new Path(input + CENTROID_FILE_NAME);
            DistributedCache.addCacheFile(hdfsPath.toUri(), conf);
        } else {
            Path hdfsPath = new Path(again_input + OUTPUT_FILE_NAME);
            DistributedCache.addCacheFile(hdfsPath.toUri(), conf);
        }
        conf.setJobName(JOB_NAME);
        //conf.setNumReduceTasks(2);
        conf.setMapOutputKeyClass(DoubleWritable.class);
        conf.setMapOutputValueClass(DoubleWritable.class);
        conf.setOutputKeyClass(DoubleWritable.class);
        conf.setOutputValueClass(Text.class);
        conf.setMapperClass(Map.class);
        conf.setNumMapTasks(4);
        conf.setReducerClass(Reduce.class);
        conf.setInputFormat(TextInputFormat.class);
        conf.setOutputFormat(TextOutputFormat.class);
        FileInputFormat.setInputPaths(conf, new Path(input + DATA_FILE_NAME));
        FileOutputFormat.setOutputPath(conf, new Path(output));
        JobClient.runJob(conf);
        Path ofile = new Path(output + OUTPUT_FILE_NAME);   

        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI("hdfs://127.0.0.1:9000"), configuration);
        Path filePath = new Path(output + OUTPUT_FILE_NAME);
        BufferedReader br = new BufferedReader(new InputStreamReader(fs.open(filePath)));
        List<Double> centers_next = new ArrayList<Double>();
        String line = br.readLine();
        while (line != null) {
            String[] sp = line.split("\t| ");
            double c = Double.parseDouble(sp[0]);
            centers_next.add(c);
            line = br.readLine();
        }
        br.close();
        String prev;
        if (iteration == 0) {
            prev = input + CENTROID_FILE_NAME;
        } else {
            prev = again_input + OUTPUT_FILE_NAME;
        }
        Path prevfile = new Path(prev);
        FileSystem fs1 = FileSystem.get(new URI("hdfs://127.0.0.1:9000"), configuration);
        BufferedReader br1 = new BufferedReader(new InputStreamReader(fs1.open(prevfile)));
        List<Double> centers_prev = new ArrayList<Double>();
        String l = br1.readLine();
        while (l != null) {
            String[] sp1 = l.split(SPLITTER);
            double d = Double.parseDouble(sp1[0]);
            centers_prev.add(d);
            l = br1.readLine();
        }
        br1.close();
        Collections.sort(centers_next);
        Collections.sort(centers_prev);
        Iterator<Double> it = centers_prev.iterator();
        for (double d : centers_next) {
            double temp = it.next();
            if (Math.abs(temp - d) <= 0.1) {
                isdone = true;
            } else {
                isdone = false;
                break;
            }
        }
        ++iteration;
        again_input = output;
        output = OUT + System.nanoTime();
    }
    long endTime   = System.currentTimeMillis();
    long totalTime = endTime - startTime;
    System.out.println(totalTime);
}

PS。我是Hadoop和MapReduce的新手。

3 个答案:

答案 0 :(得分:2)

给定作业的映射数通常由输入文件中的输入拆分数驱动,而不是由setNumMapTasks()或mapred.map.tasks参数驱动。为每个输入拆分生成一个Map任务。 mapred.map.tasks参数只是输入地图数量的一个提示。可以使用setNumMapTasks()手动增加map任务的数量,它可用于增加map任务的数量,但不会将数量设置为低于Hadoop通过拆分输入数据确定的数量。

http://wiki.apache.org/hadoop/HowManyMapsAndReduces

答案 1 :(得分:1)

您可以使用setNumMapTasksconf.set('mapred.map.tasks','numberofmappersyouwanttoset')更改映射器的数量(但建议配置)但不保证将设置映射器实例。  此外,它取决于inputsplits。

您也可以更改减速机的数量。使用你编写的代码。

结论:

  

设置地图数量 - 建议(实际上基于inputsplits   即输入文件的总块数。

     

设置减速机数量 - 需求

除了来自 @radkris 的回答中的地图符号和缩减器数量之外,请参阅。看看this

答案 2 :(得分:1)

Apache Map Reduce Tutorial提供了更多信息。

有多少地图?

  

地图数量通常由输入的总大小驱动,即输入文件的总块数。

地图的正确并行度似乎是每个节点大约10-100个地图 ,尽管已经为非常cpu-light设置了300个地图地图任务。任务设置需要一段时间,因此最好是地图至少需要一分钟才能执行。

因此,如果您期望10TB的输入数据并且块大小为128MB,那么最终会得到82,000个映射,除非Configuration.set(MRJobConfig.NUM_MAPS, int)(仅提供框架提示)用于设置它甚至更高。