尝试通过在hadoop中使用Insert overwrite partition命令压缩hive分区下的文件来解决小文件问题。
查询:
SET hive.exec.compress.output=true;
SET mapred.max.split.size=256000000;
SET mapred.output.compression.type=BLOCK;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set hive.merge.mapredfiles=true;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=256000000;
INSERT OVERWRITE TABLE tbl1 PARTITION (year=2016, month=03, day=11)
SELECT col1,col2,col3 from tbl1
WHERE year=2016 and month=03 and day=11;
输入文件:
出于测试目的,我在HDFS的hive分区(2016/03/11)下有三个文件,每个文件的大小为40 MB。
2016/03/11 / file1.csv
2016/03/11 / file2.csv
2016/03/11 / file3.csv
示例我的块大小是128,所以我想只创建一个输出文件。但我得到3个不同的压缩文件。
请帮助我获取配置单元配置以限制输出文件大小。如果我没有使用压缩,我会收到单个文件。
Hive版本:1.1
答案 0 :(得分:2)
有趣的是,在使用压缩时指定分区时仍然会获得3个文件,因此您可能希望查看动态分区或放弃分区并关注作业创建的映射器和缩减器的数量。如果您的文件很小,我可以看到您希望它们如何在目标上的一个文件中完成,但之后我还会质疑是否需要对它们进行压缩。
目标中创建的文件数量与reducer或mappers的数量直接相关。如果您编写的SQL需要减少,那么创建的文件数将与作业中使用的Reducer数相同。这可以通过设置作业中使用的减速器数来控制。
set mapred.reduce.tasks = 1;
在您的示例SQL中,很可能不会使用任何缩减器,因此目标中的文件数等于所使用的映射器数等于源中的文件数。在仅限地图的作业上控制输出文件的数量并不容易,但可以尝试许多配置设置。
设置组合小输入文件以便生成更少的映射器,默认为false。
set hive.hadoop.supports.splittable.combineinputformat = true;
尝试为输入文件设置一个以字节为单位的阈值,低于此阈值的任何内容都会尝试转换为可能影响输出文件数量的地图连接。
set hive.mapjoin.smalltable.filesize = 25000000;
至于压缩,我会改变所使用的压缩类型,看看是否会对输出产生任何影响。
set hive.exec.orc.default.compress = gzip, snappy, etc...