hadoop - hadoop 如何处理非常大的单个拆分文件

标签 hadoop split mapreduce

假设您只有 1GB 的堆大小可用于每个映射器,但是 block 大小设置为 10GB,每个拆分为 10GB。映射器如何读取较大的个体拆分?

映射器会将输入缓冲到磁盘中并以循环方式处理输入拆分吗?

谢谢!

最佳答案

映射器的整体模式非常简单:

while not end of split
  (key, value) = RecordReader.next()
  (keyOut, valueOut) = map(key, value)
  RecordWriter.write(keyOut, valueOut)

通常前两个操作只关心记录的大小。例如,当 TextInputFormat 被要求输入下一行时,它将字节存储在缓冲区中,直到找到下一行结束为止。然后缓冲区被清除。等等

map 实现由您决定。如果你不把东西存储在你的映射器中,那么你就没事了。如果您希望它是有状态的,那么您可能会遇到麻烦。确保您的内存消耗是有限的。

在最后一步中,映射器写入的键和值存储在内存中。然后对它们进行分区和排序。如果内存缓冲区变满,那么它的内容就会溢出到磁盘(无论如何最终都会溢出,因为即使在映射器消失后,reducers 也需要能够下载分区文件)。

所以你的问题的答案是:是的,会没事的。

可能引起麻烦的是:

  • 大记录(指数缓冲区增长 + 内存副本 => 显着到疯狂的内存开销)
  • 在映射器中存储来自先前键/值的数据
  • 在自定义(输入|输出)格式实现中存储来自前一个键/值的数据(如果有的话)

如果您想了解更多,这里有几个切入点:

  • Mapper.java你可以看到 while 循环
  • LineRecordReader您可以看到 TextInputFormat
  • 如何读取一行
  • 您很可能想了解溢出机制,因为它会影响您的工作绩效。 See theses Cloudera slides例如。然后您将能够决定什么是您的用例的最佳设置(大分割与小分割)。

关于hadoop - hadoop 如何处理非常大的单个拆分文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25317050/

相关文章:

hadoop - 如何将 ZooKeeper 与 Hadoop 一起用于在 reducer 之间共享读/写变量

mongodb - 如何在mongoDB中使用mapReduce存储来自hdfs的处理数据

java - hadoop Job 弃用类的替代品是什么

java - Hadoop 中失败文件的重试处理

python - hadoop 2.4.0 使用 TAB 作为分隔符的流式通用解析器选项

python - 将列表分成不同名称的列表

python - 拆分功能 - 避免最后的空白空间

java - Scala - 意外的 MapReduce 行为 - 偶数的平方

java - 获取标签之间的子字符串

mysql - 比较大数据集