一、小文件形成的原因:
(1)动态分区插入数据,产生大量的小文件,从而导致 map 数量剧增;
(2)reduce 数量越多,小文件也越多,reduce 的个数和输出文件个数一致;
(3)数据源本身就是大量小文件;
二、小文件的危害:
(1)在 HDFS 中, 每个文件均 按块存储, 每个文件在 NameNode 中存储大约占 150 个字节, 与块大小无关, 如果小文件过多,则会耗尽 NameNode 中的大多数内存。
(2)从Hive角度看,小文件过多也会影响 MR 的执行任务的数量, 一个小文件会开启一个 MapTask,同时 一个map会开一个JVM去执行 , 任务过多则会导致频繁的开启关闭, 浪费大量的资源,严重影响性能。
三、解决小文件问题常见方法:
解决小文件问题的本质就是将小文件进行合并,可以通过以下几种方式解决小文件问题:
1. 使用 hive 自带的 concatenate 命令,自动合并小文件
2. 调整参数减少Map数量、Reduce数量
(1)减少map数量: 执行Map前可以对小 文件进行合并,使用CombineHiveInputFormat,它底层是haddoop的CombineFileInputFormat方法,此方法可以在mapper中将多个文件合成一个split作为输入
(2)减少Reduce数量: Reduce的个数决定输出的文件的个数,所以可以调整Reduce的个数来控制hive表的文件数量。hive中的分区函数distribute by 正好是控制MR中partition分区的,所以通过设置reduce数量,再结合分区函数让数据均衡的进入每个reduce即可。
3. 使用 Hadoop Archive(HAR)将小文件进行归档: 使用 Hadoop 自带的 HAR 将小文件进行归档,将多个小文件打包成一个 HAR 文件,这样 NameNode 中的元数据也就存储一份。在减少 namenode 内存使用的同时,仍然可以对文件进行透明的访问。