hive与spark合并小文件,将大文件打碎成小文件

场景一:将小文件合并成大文件。

mro_hour_test表每个分区有几千个1m未压缩小文件,
以下语句是将几千个文件在输入时(map阶段)合并成150M一个的文件,插入到mro_hour_test_cp表中,
每个150M文件将会压缩成每个30M左右的gz文件。

如果 mro_hour_test表每个分区有几千个1m大小的gz文件,在插入到mro_hour_test_cp表时,会被合并成每个150M的gz文件。

set hive.hadoop.supports.splittable.combineinputformat=true;
set mapred.max.split.size=150000000;
set mapred.min.split.size.per.node=150000000;
set mapred.min.split.size.per.rack=150000000;
set mapred.max.split.size.per.node=150000000;
set mapred.max.split.size.per.rack=150000000;
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;

insert overwrite table mro_hour_test_cp partition(p_hour='${v_day}')
select 
manufactorid ,
objdifference ,

ltescthermalnoisepower 
from mro_hour_test where p_hour='${v_day}' ;

load data inpath 'hdfs://hbscjq1/user/nokia_sd/hive_db/mro_hour_test_cp/p_hour=${v_day}' OVERWRITE into table mro_hour_test partition(p_hour='${v_day}');

以上语句将 mro_hour_test 表中小文件合并成大文件,然后插入到 mro_hour_test_cp表中。
之后再将mro_hour_test_cp表中合并后的大文件load回mro_hour_test 表中,替换了小文件。

*** 注:以上语句不能将大文件打碎成小文件。***

场景二:将大文件打碎成小文件

mro_hour_test表每个文件是1G的gz文件,需要用distribute by rand() 强制启动shuffle 使数据通过reduce,
因为reduce设置最大150M。所以数据通过reducer后被分割成150M大小。

##hive版:

set hive.exec.reducers.bytes.per.reducer=150000000;
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;

insert overwrite table mro_hour_test_cp partition(p_hour='${v_day}')
select 
manufactorid ,
....
ltescthermalnoisepower 
from mro_hour_test where p_hour='${v_day}' distribute by rand();

#--------------
以下语句可将小文件合并成1G的文件。(如果只是合并文件推荐用 “场景一”hive版的效率好,因为不用启动reduce)
也可将大文件如每个文件10G大小,拆分成1G的文件。

参数 830000000 是830M,但一般情况下spark会把结果文件合并成900多M。
以下语句适合解决:spark设置分区太多,造成很多小文件情况。

##spark版:

spark-sql \
...
--conf "spark.sql.adaptive.enabled=true" \
--conf "spark.sql.adaptive.shuffle.targetPostShuffleInputSize=830000000" \
--hiveconf hive.exec.compress.output=true \
--hiveconf mapred.output.compress=true \
--hiveconf mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec \
--principal nokia_sd@BCHKDC -e "

insert overwrite table TD_NS_MR_LOCATE_H  
SELECT 
groupid,
....
null issame 
FROM TD_NS_MR_LOCATE_SRC_H WHERE ds='日期' distribute by rand();
";

注:如果有计算,有where条件过滤,spark启动了 shuffle,就不需要写 distribute by rand()

场景三:计算结束时合并小文件。

set hive.exec.reducers.bytes.per.reducer=512000000;

set hive.merge.mapfiles=true;
set hive.merge.mapredfiles=true;
set hive.merge.size.per.task=512000000;
set hive.merge.smallfiles.avgsize=512000000;

insert into result_table
select 复杂计算 from source_table where 条件可过滤大量记录;

在reduce时“条件过滤了大量记录”,因为每个reduce最大接收512M的输入数据,过滤大量记录后,假如每个reduce结果文件只有100M大小。
set hive.exec.reducers.bytes.per.reducer=512000000;

以下语句在reduce后写文件时,判断如果文件小于512M,将会再次启动map将100M的文件合并成512M.
(有的结果文件可能会超过512M,假如reduce后每个文件100M左右,有可以会出现接近600M的文件)
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles=true;
set hive.merge.size.per.task=512000000;
set hive.merge.smallfiles.avgsize=512000000;

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值