学习原文:
Hive优化之小文件合并_不积跬步无以至千里-CSDN博客_hive合并小文件
解决方案:
1. 在Map输入的时候, 把小文件合并.
-- 每个Map最大输入大小,决定合并后的文件数
set mapred.max.split.size=256000000;
-- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并
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. 在Reduce输出的时候, 把小文件合并.
-- 在map-only job后合并文件,默认true
set hive.merge.mapfiles = true;
-- 在map-reduce job后合并文件,默认false
set hive.merge.mapredfiles = true;
-- 合并后每个文件的大小,默认256000000
set hive.merge.size.per.task = 256000000;
-- 平均文件大小,是决定是否执行合并操作的阈值,默认16000000
set hive.merge.smallfiles.avgsize = 100000000;
实践:
dwd.dwd_io_xyio_track_log 表每天有55个文件,每个文件大小都是23M,想合并为256M大小的
1、map端输入端控制map文件吞吐量
set xx=xx;(具体见上面1方案)
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table dwd.dwd_io_xyio_track_log PARTITION(dt)
select * from dwd.dwd_io_xyio_track_log where dt='2021-01-26'
效果:
实现了小文件合并,变成6个300M的文件了
不足:合并后的文件大小超过256M了
2、reduce端控制输出文件大小
set yy=yy;(具体参见上面2方案)
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table dwd.dwd_io_xyio_track_log PARTITION(dt)
select * from dwd.dwd_io_xyio_track_log where dt='2021-01-27'
效果:
实现了小文件合并,变成5个300M的文件了
不足:合并后的文件大小超过256M了
3、上面两类参数同时配置
效果:
实现了小文件合并,变成5个300M的文件了
不足:合并后的文件大小超过256M了
4、调整3方案对应的参数
set hive.merge.size.per.task = 200000000; --256M改成200M
效果:还是一样,有322M的文件,超过256M
5、继续测试,map端最大size也设置为200M;
set mapred.max.split.size=200 000 000;
set hive.merge.size.per.task = 200 000 000;
效果:同上,还是有300M的文件
6、 继续测试,设置map端split.size.per.x的大小为20M
set mapred.min.split.size.per.node=20 000 000;
set mapred.min.split.size.per.rack=20 000 000;
效果:文件大小在23xM了,达到目标
体会:似乎没有通用的配置参数,不同的文件情况要设置不同的参数来实现文件合并,而不是存在1个通用的写法,所有写法都加上这些通用参数后,全部都能自动合并成理想的大小。不知道这个观念对不对。
文章评论