关于Hadoop/HDFS文件分割

20

确认以下内容是否正确: 1. 按照我的理解,当我们将一个文件复制到HDFS时,该文件(假设其大小>64MB = HDFS块大小)会被分成多个块,并且每个块都会存储在不同的数据节点上。

  1. 文件内容在复制到HDFS时已经被分割成块,并且文件的拆分不会在运行map任务时发生。map任务只是按照这样的方式调度,使它们可以处理每个最大大小为64 MB的块,并且具有数据本地性(即map任务在包含数据/块的节点上运行)

  2. 如果文件被压缩(gzipped),也会进行文件拆分,但MR确保每个文件仅由一个mapper处理,即MR将收集在其他数据节点上的gzip文件的所有块并将其全部交给单个mapper。

  3. 如果我们定义isSplitable()返回false,则与上述相同的事情将发生,即一个正在运行的机器上的一个mapper将处理文件的所有块。 MR将从不同的数据节点读取文件的所有块,并将它们提供给单个mapper使用。


一个更具描述性的标题将会是你问题的一个受欢迎的改进。 - Cody Gray
3个回答

45

David的回答基本上就击中了要害,我在这里进行一些详细解释。

这里有两个不同的概念,每个概念由Hadoop框架中的不同实体处理。

首先--

1)将文件分成块--当将文件写入HDFS时,HDFS将文件分成块并负责其复制。这通常只需做一次,并且对于运行在集群上的所有MR作业都是可用的。这是一个集群范围的配置。

其次--

2)将文件拆分为输入分片--当将输入路径传递给MR作业时,MR作业使用该路径以及配置的输入格式来将指定输入路径中的文件分割成分片,每个分片由map任务处理。输入分片的计算由输入格式每次执行作业时完成。

现在,我们一旦掌握了这个,就可以理解isSplitable()方法属于第二类。

要真正掌握这一点,请查看HDFS写数据流程(概念1)。

HDFS Write Data Flow

图中的第二点可能是拆分发生的地方,请注意,这与运行MR作业无关。

现在来看一下MR作业的执行步骤。

MR

这里的第一步是通过为作业配置的inputformat计算输入分片。

你的很多困惑源于将这两个概念混为一谈,希望这使得你更清楚了些。


在初始数据写入/分发期间是否发生数据复制?还是数据首先分布在DataNode上,然后在数据写入后由NameNode指示进行复制? - sudo soul
从官方的Apache指南中:
  1. "复制因子可以在文件创建时指定,也可以在以后更改。"
  2. "NameNode决定所有关于块的复制事宜."
这就是我为什么感到困惑的原因。
- sudo soul
没事了,我现在明白了。块分布和复制确实发生在写入时,因为在文件存储之前,其块位置和复制位置是由NameNode确定的。 - sudo soul

17

您的理解还不够全面。我要指出有两个几乎独立的过程:将文件分割为HDFS块和将文件分割为不同mapper进行处理。


HDFS根据定义的块大小将文件分割成块。


每种输入格式都有自己的逻辑,可以将文件拆分为独立处理的不同mapper的部分。FileInputFormat的默认逻辑是按HDFS块拆分文件。您可以实现任何其他逻辑。


通常情况下,压缩技术会影响拆分,因此我们采用块压缩技术来使压缩数据得以拆分。这意味着文件的每个逻辑部分(块)都会被独立压缩。


2
你好,David,感谢你的澄清。如果我的文件大小为128 MB,我猜在这种情况下,HDFS会将其分成两个块,每个块的大小为64 MB(假设HDFS块大小为64 MB)。这些块可能存储在不同的机器上。现在,如果我使用自己的FileInputFormat来扩展TextInputFormat并在“isSplitable()”中返回false,那么行为将会是什么样子?也就是说,是否只会有一个Mapper接收两个输入块(即整个文件由一个Mapper处理),或者会有两个Mapper,每个Mapper处理一个文件块。 - sunillp
我在这里感到困惑,我想尝试一下,但是我的自定义输入格式编译了,但在测试设置上没有运行。 - sunillp
2
如果isSplitable返回false,则文件将由一个mapper处理,无论块的数量如何。 - David Gruzman
有点困惑。如果MapReduce作业的输入是一个文件,并且它位于存储设备上(而不是HDFS上),现在我有以下疑问,请帮忙澄清。
  1. 在触发MR作业之前,HDFS是否会先将其拆分为HDFS块?因为输入数据位于存储设备上而不是HDFS上?
  2. 如果对第一个问题的回答是否定的,那么记录读取器是否会在运行时从存储设备中读取此文件的内容并将其提供给映射器?
- Raj

3
是的,当文件被复制到HDFS中时,文件内容会被分割成块。块大小可以进行配置,如果设置为128 MB,则整个128 MB将成为一个块,而不是分别分成2个64 MB的块。另外,并非必须将文件的每个块存储在单独的数据节点上。一个数据节点可能有特定文件的多个块。一个特定的块可以基于复制因子存在于多个数据节点中。

请仔细阅读问题 - 您的答案与主题无关。 - Yauheni Sivukha
我可以问一下以什么方式?标题本身就是说 - Hadoop/HDFS文件分割。我同意这不如David的回答好。但我没有发现任何与主题无关的内容。请告诉我,这样我就不会重复错误了。谢谢。 - Tariq
1
我认为这个答案是一个很好的TL;DR!得到了我的赞同。谢谢! - Bruno Ambrozio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接