一、小文件概述  

  小文件通常指文件大小要比HDFS块大小还要小很多的文件(在hadoop1.x版本的时候可以通过dfs.blocksize来设置,默认块大小为64M;在hadoop2.x版本的时候,则需要通过dfs.block.size设置,且默认大小为128M)

  如果存在大量小文件,则会对整个存储系统有一定影响:

  (1)1个文件块占用namenode150字节内存,大量小文件会占用namenode内存,影响HDFS的横向扩展能力

  (2)如果使用mapreduce处理小文件,则会增加map任务数量,增加寻址次数

二、如何解决

(1)采用HAR(Hadoop Archives)的归档方式。

  HAR为构建在其它文件系统上用于文件存档的文件系统,通常将hdfs中的多个文件打包成一个存档文件,减少namenode内存的使用,可以直接使用hadoop archive命令创建HAR文件。创建HAR的过程是在运行一个mr作业。

  har在对小文件进行存档后,原文件不会被删除,且创建之后不能改变,文件名中也不能有空格存在,否则会报异常。

(2)采用CombineFileInputFormat

  CombineFileInputFormat是一种新的inputformat,用于将多个文件合成一个单独的split,而且它还可以考虑数据的存储位置

(3)开启JVM重用

  JVM重用可以使得JVM实例在同一个job中重新使用N次,N的值可以在hadoop的mapred-site.xml文件中进行配置,通常在10-20之间。如果没有小文件,不要开启JVM重用,因为会一直占用使用到的task卡槽,直到任务完成才释放。

<property>
  <name>mapreduce.job.jvm.numtasks</name>
  <value>10</value>
  <description>How many tasks to run per jvm,if set to -
1 ,there is no limit</description>
</property>