4

假设我有一个输入文件,并且在 HDFS 中为此文件创建了三个块。假设我有三个数据节点,每个数据节点都存储一个块。如果我有 3 个输入拆分,则 3 个映射器将并行运行以处理各个数据节点的本地数据。每个映射器使用输入格式和记录读取器根据键值对获取输入。此场景使用 TextInputFormat,其中记录是文件中的完整文本行。

这里的问题是如果在第一个块的末尾有记录中断会发生什么。

1)Hadoop在这个场景中是如何读取完整记录的?

2)数据节点1是否联系数据节点2以获取完整记录?

3) 如果数据节点 2 开始处理数据并在第一行识别出不完整的记录,会发生什么?

4

3 回答 3

4
  1. Hadoop 将继续读取第一个块的末尾,直到到达 EOL 字符或 EOF。
  2. 该数据节点在数据复制之外不相互通信(当由名称节点指示时)。HDFS 客户端将从 node1 然后 node2 读取数据
  3. 一些例子来澄清
    • 如果您有一个跨越 300MB 文件且块大小为 128MB 的单行记录 - 映射器 2 和 3 将从文件的给定拆分偏移量(分别为 128MB 和 256MB)开始读取。他们都将向前跳过尝试查找下一个 EOL 字符并从该点开始记录。在此示例中,两个映射器实际上将处理 0 条记录。
    • 一个 300MB 文件,有两行 150MB 长,128MB 块大小 - 映射器 1 将处理第一行,在块 2 中查找 EOL 字符。映射器 2 将从偏移量 128MB(块 2)开始并向前扫描以查找 EOL 字符在偏移 150MB 处。它将向前扫描并找到块 3 之后的 EOF 并处理此数据。Mapper 3 将从偏移量 256MB(块 3)开始,并在遇到 EOL 字符之前向前扫描到 EOF,因此处理 0 条记录
    • 一个 300MB 的文件,有 6 行,每行 50MB 长:
      • 映射器 1 - 偏移量 0 -> 128MB,第 1 行 (0->50)、2 (50->100)、3 (100->150)
      • 映射器 2 - 偏移 128 MB -> 256 MB,第 4 行 (150->200)、5 (200->250)、6 (250->300)
      • 映射器 3 - 偏移 256 MB -> 300 MB,0 行

希望有帮助

于 2012-11-27T01:09:26.053 回答
1
  1. Hadoop 将对节点 2 进行远程读取以获取其余记录
  2. 是的
  3. 据我了解,节点 2 将忽略不完整的记录

如果您有“Hadoop:权威指南”,请查看第 246 页(最新版本),其中讨论了这个确切的问题(虽然很简短,但很遗憾)。

于 2012-11-26T13:45:40.280 回答
0

从 LineRecordReader.java 的 hadoop 源代码构造函数:我找到了一些评论:

// If this is not the first split, we always throw away first record
// because we always (except the last split) read one extra line in
// next() method.
if (start != 0) {
  start += in.readLine(new Text(), 0, maxBytesToConsume(start));
}
this.pos = start;

由此我相信(未确认)hadoop 将为每个拆分读取一个额外的行(在当前拆分结束时,在下一个拆分中读取下一行),如果不是第一次拆分,第一行将被丢弃。以免线路记录丢失和不完整

于 2015-01-27T16:05:34.480 回答