为什么我要避免在Hadoop HDFS中存储大量小文件?

时间:2017-10-21 05:12:29

标签: hadoop hdfs

我已经读过很多小文件存储在HDFS中可能会有问题,因为许多小文件意味着很多对象Hadoop NameNode内存。

但是,由于每个块都作为对象存储在命名节点中,因此对于大型文件有何不同?无论是从内存中的单个文件存储1000个块还是1000个文件中存储1000个块,是否使用的NameNode内存量相同?

关于地图工作的类似问题。因为它们是在块上运行的,所以如果块是小文件还是大文件有什么关系呢?

1 个答案:

答案 0 :(得分:2)

在高级别,您可以将Hadoop NameNode视为一个跟踪器,用于存储组成HDFS中存储的“文件”的块。块存储在HDFS集群中时用于将大文件分解为较小的块。

  • 当你在HDFS中存储了大量小文件时,还有很多块,NameNode必须跟踪内存中的所有文件和块。

当你有一个大文件时 - 例如 - 如果你把所有这些文件组合成更大的文件,首先 - 你将在HDFS中存储更少的文件,你也会有更少的文件。

首先让我们讨论文件大小,HDFS块和NameNode内存的关系:

通过示例和数字更容易看到。

此示例的HDFS NameNode block size为100 MB。

让我们假设我们有一千(1,000)个1 MB的文件,我们将它们存储在HDFS中。在HDFS中存储这些1,000个1 MB文件时,我们在HDFS集群中也会有1,000个块组成这些文件。

  • 存储在HDFS中的每个块需要大约150个字节的NameNode内存,对于那些代表1,000个1 MB文件的1,000个块,大约需要150 KB的内存。

现在,考虑我们将这1,000个1 MB文件合并或连接到一个1,000 MB文件中,并将该单个文件存储在HDFS中。在HDFS中存储1,000 MB文件时,它将根据我们的HDFS集群块大小分解为块;在此示例中,我们的块大小为100 MB,这意味着我们的1,000 MB文件将存储为HDFS群集中的十(10)个100 MB块。

  • 存储在HDFS中的每个块需要大约150个字节的NameNode内存,对于代表1 1,000 MB文件的10个块,这大约是1.5 KB的内存。

对于较大的文件,我们在HDFS集群中存储了相同的数据,但与使用许多小文件的情况相比,使用了1%的NameNode内存。

输入块和作业的Map任务数量是相关的。

对于Map任务,通常每个输入块都有1个地图任务。输入块的大小很重要,因为启动和完成新任务会产生开销;即,当Map任务完成得太快时,这个开销的数量将成为每个任务完成时间的更大部分,并且整个作业的完成可能比同一个作业慢,但输入块越少,越大。对于基于MapReduce2的作业,Map任务还涉及在资源管理层为每个任务启动和停止YARN容器,这会增加开销。 (请注意,您还可以指示MapReduce作业在处理许多小输入块时使用最小输入大小阈值来解决其中一些低效问题)