我正在研究一个hadoop map-reduce程序,我没有设置mapper和reducer,也没有从我的程序中为Job配置设置任何其他参数。我这样做是假设Job将输出与输出文件相同的输出。 但是我发现它在输出文件中打印了一些虚拟整数值,每一行用制表符分隔(我猜)。
这是我的代码:
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class MinimalMapReduce extends Configured implements Tool {
public int run(String[] args) throws Exception {
Job job = new Job(getConf());
job.setJarByClass(getClass());
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
return job.waitForCompletion(true) ? 0 : 1;
}
public static void main(String[] args) {
String argg[] = {"/Users/***/Documents/hadoop/input/input.txt",
"/Users/***/Documents/hadoop/output_MinimalMapReduce"};
try{
int exitCode = ToolRunner.run(new MinimalMapReduce(), argg);
System.exit(exitCode);
}catch(Exception e){
e.printStackTrace();
}
}
}
这是输入:
2011 22
2011 25
2012 40
2013 35
2013 38
2014 44
2015 43
这是输出:
0 2011 22
8 2011 25
16 2012 40
24 2013 35
32 2013 38
40 2014 44
48 2015 43
如何获得与输入相同的输出?
答案 0 :(得分:2)
我这样做是假设Job将输出与输出文件相同的输出
你认为这是正确的。从技术上讲,您将获得文件中的所有内容作为输出。请记住,映射器和缩减器将键值对作为输入。
映射器的输入是文件的输入分割,而减速器的输入是映射器的输出。
但我发现它在输出文件中打印一些虚拟整数值,每一行用制表符分隔
这些虚拟整数只不过是该行从文件开头的偏移量。由于您拥有的每一行都包含[4 DIGITS]<space>[2 DIGITS]<new-line>
,因此您的偏移量是八倍。
为什么你得到这个偏移,因为你还没有定义任何映射器或减速器,你可能会问?这是因为,映射器将始终运行,这将执行将每条线映射到它的偏移量的任务,并称为IdentityMapper
。
如何获得与输入相同的输出?
您可以定义一个映射器,只需将输入行映射到输出并去除偏移量。
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
// Some cool logic here
}
在上面的代码中,key
包含虚拟整数值,即偏移量。并且value
包含每行的值,一次一个。
您可以编写自己的代码,使用value
函数编写context.write
,然后不使用reducer并设置job.setNumReduceTasks(0)
以获得所需的输出。
答案 1 :(得分:0)
我同意@ philantrovert的回答,但这里是我发现的更多细节。 根据Hadoop-The Definitive Guide,它是TextInputFormat,它将偏移量添加到行号。以下是有关TextInputFormat的文档:
TextInputFormat是默认的InputFormat。每条记录都是一行输入。密钥LongWritable是行开头文件中的字节偏移量。该值是该行的内容,不包括任何行终止符(例如换行符或回车符),并打包为Text对象。因此,文件包含以下文本:
On the top of the Crumpetty Tree
The Quangle Wangle sat,
But his face you could not see,
On account of his Beaver Hat.
分为四个记录的一个分割。记录被解释为以下键值对:
(0, On the top of the Crumpetty Tree)
(33, The Quangle Wangle sat,)
(57, But his face you could not see,)
(89, On account of his Beaver Hat.)
显然,密钥不是行号。这通常是不可能实现的,因为文件被分成字节而不是行边界的分割。拆分是独立处理的。行号实际上是一个连续的概念。您必须在使用它们时保留行数,因此可以知道拆分中的行号,但不能在文件中。
但是,每个分支的文件中的偏移量与其他分割分开是已知的,因为每个分割都知道前面分割的大小,只是将其添加到分割中的偏移量以生成全局文件偏移量。对于需要每行唯一标识符的应用程序,偏移量通常是足够的。结合文件名,它在文件系统中是唯一的。当然,如果所有线都是固定宽度,计算线数只是将偏移除以宽度。