Java mapreduce.TextInputFormat hadoop
我是hadoop的初学者。我遇到了一个定制的RecordReader程序,它一次读取3行,并将3行输入的次数输出给映射器 我能够理解为什么要使用RecordReader,但是当input format类基本上扩展mapreduce.TextInputFormat类时,我看不出每个InputSplit如何包含3行。 根据我的理解,TextInputFormat类为每行(每行\n)发出一个InputSplit 那么RecordReader如何从每个InputSplit中读取3行呢?请有人解释一下这是怎么可能的。Java mapreduce.TextInputFormat hadoop,java,hadoop,recordreader,Java,Hadoop,Recordreader,我是hadoop的初学者。我遇到了一个定制的RecordReader程序,它一次读取3行,并将3行输入的次数输出给映射器 我能够理解为什么要使用RecordReader,但是当input format类基本上扩展mapreduce.TextInputFormat类时,我看不出每个InputSplit如何包含3行。 根据我的理解,TextInputFormat类为每行(每行\n)发出一个InputSplit 那么RecordReader如何从每个InputSplit中读取3行呢?请有人解释一下这是
提前谢谢 您需要了解
TextInputFormat
的实现才能找到答案
让我们深入研究代码。我将介绍新的MapReduceAPI,但“旧的”MapRedAPI非常类似
正如您所说,从用户的角度来看,TextInputFormat
根据一些新行字符将拆分拆分为记录。我们走吧
你可以看到这个类几乎是空的。关键功能是createRecord
,由InputFormat
@Override
public RecordReader<LongWritable, Text> createRecordReader(
InputSplit split,
TaskAttemptContext context
) {
return new LineRecordReader();
}
}
MapContextImpl:
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
return reader.nextKeyValue();
}
现在请仔细阅读您提供的此链接。你会看到:
扩展NLinesInputFormat
并仅覆盖TextInputFormat
。基本上,使用createRecordReader
您可以提供自己的LineReader
。您希望扩展RecordReader
,而不是层次结构中的另一个更高的类,因为它已经处理了在该级别完成的所有事情,并且您可能需要(压缩、不可拆分格式等)TextInputFormat
完成真正的工作。在NLinesRecordReader
中,它执行从提供的initialize
的右侧偏移量处查找InputSplit
InputStream所需的操作。它还创建一个
,与LineReader
TextInputFormat
- 在
方法中,您将看到调用nextKeyValue
三次以获得三行(加上一些逻辑以正确处理角落情况,如记录过大、行尾、拆分结束)LineReader.readLine()
希望它能帮助你。关键是要理解API的总体设计以及每个部分如何相互作用。您需要了解
TextInputFormat
的实现才能找到答案
让我们深入研究代码。我将介绍新的MapReduceAPI,但“旧的”MapRedAPI非常类似
正如您所说,从用户的角度来看,TextInputFormat
根据一些新行字符将拆分拆分为记录。我们走吧
你可以看到这个类几乎是空的。关键功能是createRecord
,由InputFormat
@Override
public RecordReader<LongWritable, Text> createRecordReader(
InputSplit split,
TaskAttemptContext context
) {
return new LineRecordReader();
}
}
MapContextImpl:
@Override
public boolean nextKeyValue() throws IOException, InterruptedException {
return reader.nextKeyValue();
}
现在请仔细阅读您提供的此链接。你会看到:
扩展NLinesInputFormat
并仅覆盖TextInputFormat
。基本上,使用createRecordReader
您可以提供自己的LineReader
。您希望扩展RecordReader
,而不是层次结构中的另一个更高的类,因为它已经处理了在该级别完成的所有事情,并且您可能需要(压缩、不可拆分格式等)TextInputFormat
完成真正的工作。在NLinesRecordReader
中,它执行从提供的initialize
的右侧偏移量处查找InputSplit
InputStream所需的操作。它还创建一个
,与LineReader
TextInputFormat
- 在
方法中,您将看到调用nextKeyValue
三次以获得三行(加上一些逻辑以正确处理角落情况,如记录过大、行尾、拆分结束)LineReader.readLine()
希望它能帮助你。关键是要理解API的总体设计,以及每个部分如何相互作用。有些理解。但这让我产生了另一个看似无关紧要的疑问——比如一个1000000行的文本文件会生成多少个
inputspilt
s?单个节点设置是否只创建一个InputSplit
?也许对你有帮助。基本上,一次拆分->一个映射器和一个HDFS块->一次拆分(但是,可以使用mapred.max.split.size
等属性来调整拆分)。当映射程序启动时,它知道自己的拆分,并要求RecordReader使用作业配置中定义的InputFormat。然后,它运行一个while循环,为每个记录调用映射函数,直到RecordReader返回false(即拆分结束)。这是可以理解的。但这让我产生了另一个看似无关紧要的疑问——比如一个1000000行的文本文件会生成多少个inputspilt
s?单个节点设置是否只创建一个InputSplit
?也许对你有帮助。基本上,一次拆分->一个映射器和一个HDFS块->一次拆分(但是,可以使用mapred.max.split.size
等属性来调整拆分)。当映射程序启动时,它知道其拆分,并要求RecordReader使用作业配置中定义的InputFormat。然后,它运行while循环,为每个记录调用映射函数,直到RecordReader返回false(即拆分结束)。