记录阅读器和记录边界

时间:2012-11-26 09:43:06

标签: hadoop mapreduce

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

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

1)在这种情况下Hadoop如何读取完整记录?

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

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

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

  1. Hadoop将对节点2进行远程读取以获取剩余的记录
  2. 根据我的理解,节点2将忽略不完整的记录
  3. 如果您有“Hadoop:The Definitive Guide”,请查看第246页(最新版本),该页面讨论了这个确切的问题(不过很简单,不幸的是)。

答案 2 :(得分: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将为每个分割读取一个额外的行(在当前分割结束时,在下一个分割中读取下一行),如果不是第一次分割,则第一行将被丢弃。 所以没有行记录会​​丢失和不完整