目录

  • HDFS上的小文件问题
  • MapReduce上的小文件问题
  • 解决方案
  • 第一种情况
  • 第二种情况
  • HAR File
  • SequenceFile
  • HBase


HDFS上的小文件问题

  首先,在HDFS中,任何一个文件,目录或者block在NameNode节点的内存中均以元数据表示,而这受到NameNode物理内存容量的限制。
  其次,处理小文件并非Hadoop的设计目标,HDFS的设计目标是流式访问大数据集(TB级别)。因而,在HDFS中存储大量小文件是很低效的。访问大量小文件经常会导致大量的寻找,以及不断的从一个DatanNde跳到另一个DataNode去检索小文件,严重影响性能。
  最后,处理大量小文件速度远远小于处理同等大小的大文件的速度。每一个小文件要占用一个slot,而task启动将耗费大量时间甚至大部分时间都耗费在启动task和释放task上。

MapReduce上的小文件问题

  Map任务(task)一般一次处理一个块大小的输入(input)(默认使用FileInputFormat)。如果文件非常小,并且拥有大量的这种小文件,那么每一个map task都仅仅处理非常小的input数据,因此会产生大量的map tasks,每一个map task都会额外增加bookkeeping开销。
  Hadoop中有一些特性可以用来减轻bookkeeping开销:可以在一个JVM中允许task JVM重用,以支持在一个JVM中运行多个map task,以此来减少JVM的启动开销(通过设置mapred.job.reuse.jvm.num.tasks属性,默认为1,-1表示无限制)。另一种方法是使用MultiFileInputSplit,它可以使得一个map中能够处理多个split。

解决方案

这两种情况需要有不同的解决方式。

第一种情况

  对于第一种情况,文件是许多记录(Records)组成的,那么可以通过调用HDFS的sync()方法(和append方法结合使用),每隔一定时间生成一个大文件,或者可以通过写一个程序来来合并这些小文件。

第二种情况

  对于第二种情况,就需要某种形式的容器通过某种方式来对这些文件进行分组。Hadoop提供了一些选择:

HAR File

  Hadoop Archives (HAR files)是在0.18.0版本中引入到HDFS中的,它的出现就是为了缓解大量小文件消耗NameNode内存的问题。HAR文件是通过在HDFS上构建一个分层文件系统来工作。HAR文件通过hadoop archive命令来创建,而这个命令实际上是运行了一个MapReduce作业将小文件进行合并几个大文件。对于client端来说,使用HAR文件没有任何的改变:所有的原始文件都可见以及可访问,但是在HDFS中中文件数却减少了。

  读取HAR中的文件不如读取HDFS中的文件更有效,并且实际上可能较慢,因为每个HAR文件访问需要读取两个索引文件以及还要读取数据文件本身(如下图)。尽管HAR文件可以用作MapReduce的输入,但是没有特殊的魔法允许MapReduce直接操作HAR在HDFS块上的所有文件。可以考虑通过创建一种input format,充分利用HAR文件的局部性优势,但是目前还没有这种input format。需要注意的是:MultiFileInputSplit,即使在HADOOP-4565的改进,但始终还是需要每个小文件的寻找。

hadoop 合并小文件 hadoop小文件问题_hadoop 合并小文件

SequenceFile

  通常对于"小文件问题"的回应会是:使用序列文件(SequenceFile)。这种方法的思路是,使用文件名(filename)作为key,并且文件内容(file contents)作为value,如下图。对于10,000个100KB小文件问题上,可以编写一个程序将它们放入一个单一的SequenceFile,然后可以流式处理它们(直接处理或使用MapReduce)操作SequenceFile。这样同时会带来两个优势:(1)SequenceFiles是可拆分的,因此MapReduce可以将它们分成块并独立地对每个块进行操作;(2)它们同时支持压缩,不像HAR。 在大多数情况下,块压缩是最好的选择,因为它将压缩几个记录为一个块,而不是一个记录压缩一个块。

hadoop 合并小文件 hadoop小文件问题_HDFS_02


SequenceFile是以Java为中心的。,将现有数据转换为SequenceFile可能很慢。 但是,完全可以并行创建SequenceFile的集合。与HAR文件不同,没有办法列出SequenceFile中的所有键,所以不能读取整个文件。Map File,就像对键进行排序的SequenceFile,只维护了部分索引,所以也不能列出所有的键,如下图。

hadoop 合并小文件 hadoop小文件问题_HDFS_03

HBase

  如果生产很多小文件,那么根据访问模式,不同类型的存储可能更合适。HBase以Map Files(带索引的SequenceFile)方式存储数据,如果需要随机访问来执行MapReduce式流式分析,这是一个不错的选择