我的文件大小为100 MB,并且默认块大小为64 MB。如果我没有设置输入分割大小,则默认分割大小将是块大小。现在拆分大小也是64 MB。
当我将这个100 MB文件加载到HDFS时,100 MB文件将分成2个块。即64 MB和36 MB。例如,下面是一首大小为100 MB的诗歌。如果我将这些数据加载到HDFS中,例如从第1行到第16行的一半,就像一个分割/块一样只有64 MB(最多"它使" )和剩余的第16行(孩子笑和播放)的一半到文件末尾作为第二个块(36 MB)。将有两个映射器工作。
我的问题是第一个映射器将如何考虑第16行(即块1的第16行),因为块只有一半的行,或者第二个映射器将如何考虑块2的第一行,因为它是也有一半的线。
Mary had a little lamb
Little lamb, little lamb
Mary had a little lamb
Its fleece was white as snow
And everywhere that Mary went
Mary went, Mary went
Everywhere that Mary went
The lamb was sure to go
He followed her to school one day
School one day, school one day
He followed her to school one day
Which was against the rule
It made the children laugh and play
Laugh and play, laugh and play
It made the children laugh and play
To see a lamb at school
And so the teacher turned him out
Turned him out, turned him out
And so the teacher turned him out
But still he lingered near
And waited patiently
Patiently, patiently
And wai-aited patiently
Til Mary did appear
或者在拆分64 MB时,而不是分割单行,hadoop会考虑整行16吗?
答案 0 :(得分:1)
在hadoop数据中,根据输入分割大小和块大小读取数据。
文件根据大小分为多个FileSplits。使用与输入中的偏移相对应的start参数初始化每个Input分割。
当我们初始化LineRecordReader时,它会尝试实例化一个开始读取行的LineReader。
如果定义了CompressionCodec,它会处理边界。 因此,如果InputSplit的开头不为0,则回溯1个字符然后跳过第一行(遇到\ n或\ r \ n).Backtrack确保您不跳过有效行。
以下是代码:
if (codec != null) {
in = new LineReader(codec.createInputStream(fileIn), job);
end = Long.MAX_VALUE;
} else {
if (start != 0) {
skipFirstLine = true;
--start;
fileIn.seek(start);
}
in = new LineReader(fileIn, job);
}
if (skipFirstLine) { // skip first line and re-establish "start".
start += in.readLine(new Text(), 0,
(int)Math.min((long)Integer.MAX_VALUE, end - start));
}
this.pos = start;
由于分割是在客户端计算的,因此映射器不需要按顺序运行,每个映射器都知道它是否需要丢弃第一行。
因此,在你的情况下,第一个块B1,将读取从偏移0到的数据“这让孩子们笑了起来”行
Block B2将从“看到学校的羊羔”行读取数据到最后一行偏移量。
您可以参考这些参考:
https://hadoopabcd.wordpress.com/2015/03/10/hdfs-file-block-and-input-split/
How does Hadoop process records split across block boundaries?
答案 1 :(得分:0)
第一个映射器将读取整个第16行(它将继续读取,直到找到并结束行字符)。
如果您还记得,为了应用mapreduce,您的输入必须按键值对进行组织。对于恰好在Hadoop中默认的TextInputFormat,这些对是:(offset_from_file_beginning,line_of_text)。文本被分解为基于' \ n'的键值对。字符。因此,如果一行文本超出输入分割的大小,则映射器将继续读取,直到找到' \ n'。