Hadoop MapReduce还原程序之间的作业分配

Hadoop MapReduce还原程序之间的作业分配,hadoop,mapreduce,cloud,Hadoop,Mapreduce,Cloud,我开发了一个小的mapreduce程序。当我打开流程日志时,我看到框架创建了一个map和两个reducer。我只有一个输入文件和两个输出文件。现在请告诉我 1) Number of mapper and reducer are created by framework or it can be changed? 2) Number of output files always equal to number of reducers? i.e. each reducer creates it

我开发了一个小的mapreduce程序。当我打开流程日志时,我看到框架创建了一个map和两个reducer。我只有一个输入文件和两个输出文件。现在请告诉我

1) Number of mapper and reducer are created by framework or it can be changed?
2) Number of output files always equal to number of reducers? i.e. each reducer
   creates its   own output file?
3) How one input file is distributed among mappers? And output of one mapper is 
   distributed among multiple reducers (this is done by framework or you can change)?
4) How to manage when multiple input files are there i.e. A directory ,
   containing input files?

请回答这些问题。我是MapReduce的初学者。

让我尝试回答您的问题。请告诉我你认为哪里不对-

1个映射器和还原器是由框架创建的还是可以更改

创建的映射任务总数取决于由HDFS块组成的逻辑拆分的总数。因此,固定贴图任务的数量可能并不总是可行的,因为不同的文件可能具有不同的大小,并且具有不同的总块数。因此,如果您使用的是TextInputFormat,则每个逻辑拆分大致相当于一个块,并且不可能固定总映射任务的数量,因为对于每个文件,可以创建不同数量的块

与映射器的数量不同,还原器可以是固定的

2输出文件的数量始终等于减速机的数量?i、 e.每个减速器 创建自己的输出文件

在某种程度上是的,但是有一些方法可以从一个减速机创建多个输出文件。例如:

3一个输入文件如何在映射者之间分发?一个映射器的输出是 分布在多个简化程序中,这是由框架完成的,还是可以更改

HDFS中的每个文件都由块组成。这些块被复制并可以保留在多个节点机器中。然后计划映射任务在这些块上运行。 映射任务可以运行的并发级别取决于每台机器拥有的处理器数量。 例如,对于一个文件,如果计划了10000个映射任务,则根据整个集群的处理器总数,一次只能并发运行100个映射任务

默认情况下,Hadoop使用HashPartitioner,它计算从映射器发送到框架的键的哈希代码,并将它们转换为分区

例如:

  public int getPartition(K2 key, V2 value,
                          int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }
正如您在上面看到的,分区是从基于哈希代码固定的还原器总数中选择的。因此,如果numReduceTask=4,则返回的值将介于0到3之间

4当存在多个输入文件(即目录)时如何管理, 包含输入文件


Hadoop支持将包含多个文件的目录作为作业的输入。

让我尝试回答您的问题。请告诉我你认为哪里不对-

1个映射器和还原器是由框架创建的还是可以更改

创建的映射任务总数取决于由HDFS块组成的逻辑拆分的总数。因此,固定贴图任务的数量可能并不总是可行的,因为不同的文件可能具有不同的大小,并且具有不同的总块数。因此,如果您使用的是TextInputFormat,则每个逻辑拆分大致相当于一个块,并且不可能固定总映射任务的数量,因为对于每个文件,可以创建不同数量的块

与映射器的数量不同,还原器可以是固定的

2输出文件的数量始终等于减速机的数量?i、 e.每个减速器 创建自己的输出文件

在某种程度上是的,但是有一些方法可以从一个减速机创建多个输出文件。例如:

3一个输入文件如何在映射者之间分发?一个映射器的输出是 分布在多个简化程序中,这是由框架完成的,还是可以更改

HDFS中的每个文件都由块组成。这些块被复制并可以保留在多个节点机器中。然后计划映射任务在这些块上运行。 映射任务可以运行的并发级别取决于每台机器拥有的处理器数量。 例如,对于一个文件,如果计划了10000个映射任务,则根据整个集群的处理器总数,一次只能并发运行100个映射任务

默认情况下,Hadoop使用HashPartitioner,它计算从映射器发送到框架的键的哈希代码,并将它们转换为分区

例如:

  public int getPartition(K2 key, V2 value,
                          int numReduceTasks) {
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
  }
正如您在上面看到的,分区是从基于哈希代码固定的还原器总数中选择的。因此,如果numReduceTask=4,则返回的值将介于0到3之间

4当存在多个输入文件(即目录)时如何管理, 包含输入文件


Hadoop支持由多个文件组成的目录作为作业的输入。

如“SSaikia_JtheRocker”所述,映射器任务是根据HDFS块上的逻辑拆分总数创建的。 我想在问题3中添加一些东西,一个输入文件如何在映射者之间分布?一个映射器的输出分布在多个还原器中,这是由框架或yo完成的 你能改变吗? 例如,考虑我的单词计数程序,它计算文件中单词的数量如下:

公共类WCMapper扩展了映射器{

@Override
public void map(LongWritable key, Text value, Context context) // Context context is output
        throws IOException, InterruptedException {

    // value = "How Are You"
    String line = value.toString(); // This is converting the Hadoop's "How Are you" to Java compatible "How Are You"

    StringTokenizer tokenizer = new StringTokenizer (line); // StringTokenizer returns an array tokenizer = {"How", "Are", "You"}

    while (tokenizer.hasMoreTokens()) // hasMoreTokens is a method in Java which returns boolean values 'True' or 'false'
    {
        value.set(tokenizer.nextToken()); // value's values are overwritten with "How" 
        context.write(value, new IntWritable(1)); // writing the current context to local disk
        // How, 1
        // Are, 1
        // You, 1
        // Mapper will run as many times as the number of lines 
    }
}
}

在上面的程序中,StringTokenizer将行How is you拆分为3个单词,当在while循环中使用时,映射器的调用次数与单词数相同,因此这里调用3个映射器

和reducer,我们可以指定使用“job.setNumReduceTask5;”生成输出的reducer数量陈述下面的代码片段将给您一个想法

公共类图书{

public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    // Use programArgs array to retrieve program arguments.
    String[] programArgs = new GenericOptionsParser(conf, args)
            .getRemainingArgs();
    Job job = new Job(conf);
    job.setJarByClass(BooksMain.class);
    job.setMapperClass(BookMapper.class);
    job.setReducerClass(BookReducer.class);
    job.setNumReduceTasks(5);
//job.setCombinerClassBookReducer.class

    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);

    // TODO: Update the input path for the location of the inputs of the map-reduce job.
    FileInputFormat.addInputPath(job, new Path(programArgs[0]));
    // TODO: Update the output path for the output directory of the map-reduce job.
    FileOutputFormat.setOutputPath(job, new Path(programArgs[1]));

    // Submit the job and wait for it to finish.
    job.waitForCompletion(true);
    // Submit and return immediately: 
    // job.submit();
}
}


正如“SSaikia_JtheRocker”所解释的,映射器任务是根据HDFS块上的逻辑拆分总数创建的。 我想在问题3中添加一些东西,一个输入文件如何在映射者之间分布?一个映射器的输出分布在多个还原器中,这是由框架完成的,还是可以更改? 例如,考虑我的单词计数程序,它计算文件中单词的数量如下:

公共类WCMapper扩展了映射器{

@Override
public void map(LongWritable key, Text value, Context context) // Context context is output
        throws IOException, InterruptedException {

    // value = "How Are You"
    String line = value.toString(); // This is converting the Hadoop's "How Are you" to Java compatible "How Are You"

    StringTokenizer tokenizer = new StringTokenizer (line); // StringTokenizer returns an array tokenizer = {"How", "Are", "You"}

    while (tokenizer.hasMoreTokens()) // hasMoreTokens is a method in Java which returns boolean values 'True' or 'false'
    {
        value.set(tokenizer.nextToken()); // value's values are overwritten with "How" 
        context.write(value, new IntWritable(1)); // writing the current context to local disk
        // How, 1
        // Are, 1
        // You, 1
        // Mapper will run as many times as the number of lines 
    }
}
}

在上面的程序中,StringTokenizer将行How is you拆分为3个单词,当在while循环中使用时,映射器的调用次数与单词数相同,因此这里调用3个映射器

和reducer,我们可以指定使用“job.setNumReduceTask5;”生成输出的reducer数量陈述下面的代码片段将给您一个想法

公共类图书{

public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    // Use programArgs array to retrieve program arguments.
    String[] programArgs = new GenericOptionsParser(conf, args)
            .getRemainingArgs();
    Job job = new Job(conf);
    job.setJarByClass(BooksMain.class);
    job.setMapperClass(BookMapper.class);
    job.setReducerClass(BookReducer.class);
    job.setNumReduceTasks(5);
//job.setCombinerClassBookReducer.class

    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);

    // TODO: Update the input path for the location of the inputs of the map-reduce job.
    FileInputFormat.addInputPath(job, new Path(programArgs[0]));
    // TODO: Update the output path for the output directory of the map-reduce job.
    FileOutputFormat.setOutputPath(job, new Path(programArgs[1]));

    // Submit the job and wait for it to finish.
    job.waitForCompletion(true);
    // Submit and return immediately: 
    // job.submit();
}
}