如何处理Hive中小文件合并的问题
(1)问题分析
考官主考的是对hive中常见问题解决方案的使用,小文件的产生、影响和解决方案都要讲出来。
(2)核心问题讲解
小文件是如何产生的
1)动态分区插入数据,产生大量的小文件,从而导致map数量剧增。
2)reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的)。
3)数据源本身就包含大量的小文件。
小文件问题的影响
1)从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。
2)在HDFS中,每个小文件对象约占150byte,如果小文件过多会占用大量元数据内存。这样NameNode内存容量严重制约了集群的扩展。
小文件问题的解决方案
从小文件产生的途经就可以从源头上控制小文件数量,方法如下:
1)因为SequenceFile压缩率最低,所以使用Sequencefile作为表存储格式,不要用textfile,在一定程度上可以减少小文件。
2)减少reduce的数量(可以使用参数进行控制)。
3)少用动态分区,用时记得按distribute by分区。
对于已有的小文件如何处理
1)使用hadoop archive命令把小文件进行归档。
2)重建表,建表时减少reduce数量。
3)通过参数进行调节,设置map/reduce端的相关参数
(3)问题扩展
map/reduce端的相关参数的设置
1)设置map输入合并小文件的相关参数:
//每个Map最大输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256000000;
//一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;
//一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000;
//执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
2)配置Hive结果合并
我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并:
//设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true
//设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true
//设置合并文件的大小
set hive.merge.size.per.task = 25610001000
//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000
注意:对于输出结果为压缩文件形式存储的情况,要解决小文件问题,如果在Map输入前合并,对输出的文件存储格式并没有限制。但是如果使用输出合并,则必须配合SequenceFile来存储,否则无法进行合并。