许多小文件和128 Mb块大小的HDFS行为

VB_*_*VB_ 3 hadoop hdfs

我有很多(高达数十万)小文件,每个10-100 Kb.我的HDFS块大小等于128 MB.我的复制因子等于1.

每个小文件分配HDFS块有什么缺点吗?

我看到了相当矛盾的答案:

  1. 回答说最小​​的文件占用了整个块
  2. 回答说HDFS足够聪明,小文件将采用small_file_size + 300字节的元数据

我在这个答案中做了一个测试,它证明第二个选项是正确的 - HDFS没有为小文件分配整个块.

但是,批量读取HDFS中的10.000个小文件怎么样?因为10,000块和metadatas会减慢吗?有没有理由在单个块中保留多个小文件?

更新:我的用例

我只有一个用于小文件的用例,从1.000到500.000.我计算一次文件,存储它,然后一次读取它们.

1)据我所知,NameNode空间问题对我来说不是问题.500.000是绝对最大值,我永远不会有更多.如果每个小文件在NN上占用150个字节,那么我的绝对最大值是-71.52 MB,这是可以接受的.

2)Apache Spark是否消除了MapReduce问题?序列文件或HAR会帮助我解决问题吗?据我了解,Spark不应该依赖Hadoop MR,但它仍然太慢.490个文件需要38秒才能读取,3420个文件需要266秒.

sparkSession
    .read()
    .parquet(pathsToSmallFilesCollection)
    .as(Encoders.kryo(SmallFileWrapper.class))
    .coalesce(numPartitions);
Run Code Online (Sandbox Code Playgroud)

Ser*_*hiy 6

正如您已经注意到的那样,HDFS文件不会占用超出其需要的空间,但是在HDFS集群中存在小文件还有其他缺点.让我们首先解决问题而不考虑批处理:

  1. NameNode(NN)内存消耗.我不知道Hadoop 3(目前正在开发中),但在以前的版本中,NN是单点故障(您可以添加辅助NN,但最终不会替换或增强主要NN).NN负责维护内存和磁盘上的文件系统结构,并且资源有限.由NN维护的文件系统对象中的每个条目被认为是150个字节(查看此博客文章).更多文件= NN消耗更多RAM.
  2. MapReduce范例(据我所知,Spark也有相同的症状).在Hadoop中,每个分割器都会分配Mappers(默认情况下对应于块),这意味着,对于每个小文件,您需要启动一个新的Mapper来处理其内容.问题是对于小文件来说,实际上Hadoop启动Mapper需要的工作量远远超过处理文件内容.基本上,您的系统将执行不必要的启动/停止Mappers的工作,而不是实际处理数据.这就是Hadoop处理快速1 128MBytes文件(块大小为128MBy)而不是128个1MBytes文件(具有相同块大小)的原因.

现在,如果我们谈论批处理,那么您可以选择的选项很少:HAR,序列文件,Avro架构等.这取决于用例来准确回答您的问题.假设您不想合并文件,在这种情况下,您可能正在使用HAR文件(或任何其他具有高效归档和索引的解决方案).在这种情况下,NN问题得到解决,但Mapper的数量仍将等于分割数.如果将文件合并为大文件是一个选项,您可以使用序列文件,它基本上将小文件聚合成更大的文件,解决了一些问题.在这两种情况下,虽然您无法直接更新/删除信息,就像您可以使用小文件一样,因此管理这些结构需要更复杂的机制.

一般来说,维护许多小文件的主要原因是尝试进行快速读取,我建议看一下像HBase这样的不同系统,这些系统是为快速数据访问而不是批量处理而创建的.