我开发了一个小型mapreduce程序。当我打开进程日志时,我看到框架创建了一个map和两个reducers。我只有一个输入文件,有两个输出文件。现在请告诉我
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的初学者。
答案 0 :(得分:4)
让我试着回答你的问题。如果您认为不正确,请告诉我 -
1)mapper和reducer的数量是由框架创建的还是可以更改?
创建的映射任务总数取决于从HDFS块中进行的逻辑拆分总数。因此,修复地图任务的数量可能并不总是可能的,因为不同的文件可以具有不同的大小并且具有不同数量的总块。因此,如果您使用的是TextInputFormat,则大致每个逻辑分割都等于一个块,并且无法确定总映射任务的固定数量,因为对于每个文件,可以创建不同数量的块。
与地图绘制器数量不同,可以修复减速器。
2)输出文件的数量总是等于reducer的数量?即每个减速器 创建自己的输出文件?
在某种程度上是,但有一些方法可以从reducer创建多个输出文件。例如:MultipleOutputs
3)如何在映射器之间分配一个输入文件?并且一个映射器的输出是 分布在多个Reducer之间(这是通过框架完成的,或者你可以改变)?
HDFS中的每个文件都由块组成。这些块被复制并可以保留在多个节点(机器)中。然后安排映射任务在这些块上运行。 映射任务可以运行的并发级别取决于每台计算机具有的处理器数量。 例如。对于文件,如果安排了10,000个映射任务,则根据整个群集中的处理器总数,一次只能同时运行100个。
默认情况下,Hadoop使用HashPartitioner,它计算从Mapper发送到框架的密钥的哈希码,并将它们转换为分区。
例如:
public int getPartition(K2 key, V2 value,
int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
如上所示,从根据哈希码修复的reducer总数中选择一个分区。因此,如果numReduceTask = 4,则返回的值将介于0到3之间。
4)如何管理多个输入文件,即A目录, 包含输入文件?
Hadoop支持由多个文件组成的目录作为作业的输入。
答案 1 :(得分:0)
正如SSaikia_JtheRocker'所解释的那样。映射器任务是根据HDFS块上的逻辑拆分总数创建的。 我想在问题#3和#34中添加一些内容;如何在映射器之间分配一个输入文件?并且一个映射器的输出分布在多个reducer之间(这是通过框架完成的,或者你可以改变)?" 例如,考虑我的单词计数程序,它计算文件中的单词数量如下所示:
#公共类WCMapper扩展了Mapper {
@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分成3个单词,当在while循环中使用它时,映射器被调用的次数与单词数一样多,因此这里有3个映射器被调用。
和reducer一样,我们可以指定我们希望在使用&job; set.umNumReduceTasks(5)生成输出的减少器数量;'声明。下面的代码片段会给你一个想法。
# 公共类BooksMain {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.setCombinerClass(BookReducer.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();
}
}
#