网站首页 > 技术文章 正文
0.背景
近来我们公司搞小文件治理(小于10Mb),小文件太多的危害就不此赘述了。公司的开发人员提供的合并小文件治理配置如下:
-- 设置小文件合并
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles=true;
set hive.merge.size.per.task = 256000000 ;
set hive.merge.smallfiles.avgsize= 256000000 ;
看上去配置的没啥问题,不管是Map-only,还是MapReduce都考虑到了,只要输出的文件小于这个值,就重新启动一个MR去执行文件合并。看也符合Hive官网的配置解释
?
然而现实并非如此,废话不多说,you can you code,no can no bb.
原分析表数据在HDFS存储为551个小文件,下面所有的测试都是基于这个文件。
1.测试代码方案1
设置启动map前文件合并,先使用官方默认配置,实现文件合并测试
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; --官方默认值,也是当前平台默认值
set hive.merge.smallfiles.avgsize=16000000; --官方默认值,也是当前平台默认值
set hive.merge.size.per.task=256000000; --官方默认值,也是当前平台默认值
set hive.merge.mapfiles =true ; --官方默认值,也是当前平台默认值
set hive.merge.mapredfiles = true ; --官方默认值,也是当前平台默认值
drop table if exists FDM_SOR.T_FSA_BHVR_NEW_EXPO_D_tmp_tmp;
create table FDM_SOR.t_fsa_bhvr_new_expo_d_tmp_tmp
stored as orc
as
select
*
from FDM_SOR.t_fsa_bhvr_new_expo_d
where stat_date = '20200630'
结果:只产生了438个文件,看样子效果不错,文件变少了,但是发现还是有很多小于16Mb的文件,为啥设置了不管用呢,是不是set hive.merge.smallfiles.avgsize官方的默认值给的太小了。需要加大。看实验2.
?
?
2.测试代码方案2
设置启动map前文件合并,将set hive.merge.smallfiles.avgsize值加大,增加文件合并的Size。按照官方的说法当输出的文件平均小于16Mb时系统会再启动一个MR进行文件合并。这下该管用了吧,请看:
set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; --官方默认值,也是当前平台默认值
set hive.merge.smallfiles.avgsize=256000000; --改了这个值,由默认的16Mb,改成256Mb
set hive.merge.size.per.task=256000000; --官方默认值,也是当前平台默认值
set hive.merge.mapfiles =true ; --官方默认值,也是当前平台默认值
set hive.merge.mapredfiles = true ; --官方默认值,也是当前平台默认值
drop table if exists FDM_SOR.T_FSA_BHVR_NEW_EXPO_D_tmp_tmp;
create table FDM_SOR.t_fsa_bhvr_new_expo_d_tmp_tmp
stored as orc
as
select
*
from FDM_SOR.t_fsa_bhvr_new_expo_d
where stat_date = '20200630'
废话不多说,上结果请看
?
?结果分析:没错,第一次MR因为Combinetext启动了438个map和上面一样,果然接着又启动了一个MR,进行输出后的文件合并。看样子很DIAO。合并要求文件大小不小256Mb,然后实际呢?pappa。文件虽然减少了很多到351个,但依然有很多小文件,很多小于10Mb的文件,这个时候心里肯定一句
?
3.测试代码方案3
放大招,功夫有没有,代码走一走,加上split参数
set mapred.max.split.size=256000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set hive.merge.mapfiles = true ;
set hive.merge.mapredfiles = true ;
set hive.merge.size.per.task = 256000000 ;
set hive.merge.smallfiles.avgsize=160000000 ;
drop table if exists FDM_SOR.T_FSA_BHVR_NEW_EXPO_D_tmp_tmp;
create table FDM_SOR.T_FSA_BHVR_NEW_EXPO_D_tmp_tmp
stored as orc
as
select
*
from FDM_SOR.T_FSA_BHVR_NEW_EXPO_D
where stat_date = '20200630'
废话不多说,上结果请看:
?
?
结果分析:这下好了,全是大文件,44大文件,每个大文件都是辣么大,最小的都是48Mb。为啥加了split参数以后就生效了呢。前面单独合并小文件参数没啥效果呢?网上随便搜一下,都是这种配置这种参数的?
-- 设置小文件合并
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles=true;
set hive.merge.size.per.task = 256000000 ;
set hive.merge.smallfiles.avgsize= 256000000 ;
4.答案揭晓
因为设置上面四个参数,看上去规定了map结束,MR结束合并文件,如果文件平均小于smallfiles.avgsize启动一个新的MRj进行文件的二次合并。如果启动mr合并文件,没有问题。但是忽略了一个问题,你重新启动一个mr合并文件,这个mr是不是需要进行文件split,你这个参数搞小了,那就会产生很多task,很多map,比如很多小文件就是一个map,最终还是产生很多小文件(因为合并小文件的mr只有map)。所以必须要配合split参数才有用。具体split参数使用,参考我其他博客。
?
猜你喜欢
- 2024-11-13 一位安卓程序员入坑Flutter后整理出一份超详细的学习笔记
- 2024-11-13 真正让你明白Hive调优系列3:笛卡尔乘积,小表join大表,Mapjoin
- 2024-11-13 合并Java Stream流让你更方便的对多个集合进行整合操作
- 2024-11-13 Java 8 中那些方便又实用的 Map 函数:让你的代码更简洁高效
- 2024-11-13 北约、俄罗斯、乌克兰地图速记,看一遍过目不忘了
- 2024-11-13 或与腾讯地图合并?搜狗地图App下架
- 2024-11-13 两张图片怎样拼在一起?将两张图片拼在一起的几种方法介绍
- 2024-11-13 普京承认乌东两个“共和国”,战术成功战略失败,恐怕得不偿失
- 2024-11-13 印度独立后,多次在南亚称霸,为何却对斯里兰卡无可奈何
- 2024-11-13 多次采集的横断面数据,可以一次合并出断面图吗?
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)