Hive 相关的reduce参数设置

环境

cdh         6.3.2-1.cdh6.3.2.p0.1605554 

hive        2.1.1-cdh6.3.2 rb3393cf499504df1d2a12d34b4285e5d0c02be11

问题

有些dw宽表加工速度慢

表加工逻辑是io密集任务,不是cpu计算任务,且不涉及数量特别多表关联

过程

看了8088,发现倾斜基本发生在mapstage

看DAG调度图现象就是只分配了极少个数的map数量

spark在map阶段的分配map个数的底层原理有学习过但是本人不才没有学好.... :<

不过map看个数是 根据上游ods的文件块大小和个数来分配的,只分配很少

(dw层表默认序列化反序列化的类是 orc,blocksize也是默认的,所以不涉及可不可切分等问题)

思路1

ods文件块大小有问题的原因是 用的抽数工具是flinkx或者datax,没有调教好合适参数,导致分区内和oracle的文件保持一致,出现了不均匀或者大文件

也有可能是抽数过来以后中间件做过小文件合并导致有大文件

调整参数应该是一个很好的办法,但是我们是生产环境...所以不太好控制

所以这个思路保留~

思路2(重要)

如果无法从ods表处做处理(类似hive etl的时候处理)

那就考虑在加工的时候,也就是说在application创建,也就是在会话级别调优这个作业达到目的

总结一下两个思路就是 针对map缓慢的作业,提前etl好 依赖表 ,或者就是在读的时候控制

gpt给出的参数

set hive.merge.size.per.task=16000000 ;

--mergefile作业的时候每个task处理的数据量

--默认256



set mapred.max.split.size=8000000 ;

-- mapreduce系列的参数设置,但是spark也有用

-- 切文件的大小参数的设置

--默认256



set  hive.exec.orc.default.block.size=32000000 ;

-- orc文件的导入导出的参数配置

具体操作(重要)

set hiveexec.reducers.bytes.per.reducer;  
-- 这个参数指定了每个Reducer理的输入数据量的上限(以字节为单位)。如果作业的输入数据量超过了这个阈值,Hive会自动增加Reducer的数量,以保证每个Reducer处理的数据量不超过该阈值。这个参数的默认值是1GB。


set hive.merge.smallfiles.avgsize;
--这个参数用于控制Hive在执行文件并操作时的平均文件大小(以字节为单位)。当Hive执行文件合并操作时,它会尝试将多个小文件合并为一个或少量的大文件,以提高查询性能。该参数的默认值是256MB。


set hive.merge.size.per.task;  
--这个参数指定了每个任务(Task)执行文件合并操作时的最大输入数据大小(以字节为单位)。如果一个任务的输入数据大小超过了这个阈值,Hive会将该任务的输出结果拆分为多个文件并进行合并。该参数的默认值是256MB。


set hive.exec.orc.default.block.size:
--设置ORC文件的默认块大小。假设有一个大型数据集,每个ORC文件默认的块大小为256MB。如果想要优化查询性能,可以将块大小调整为128MB,以减少每次查询读取的数据量。
--对于一般的 union 

--元数据库里的结果是不对的,要手动加表分析 或 增加reduce阶段的操作 distribute by 


--有个小知识点,就是unionall+limit的时候可能会有bug
-- unionall+ 四个by的时候是不需要注意这个的,因为四个by都是对结果集处理的





-- 常用 distribute by rand() 随机分配
insert overwrite table tb3 partition (day='${YYYYMMDD}')
select col1 , col2 from tb1  where day='20230101'
union all 
select col1 ,col2 from tb2 where day='20230101'
distribute by col1 


-- 普通的sql 也可以执行
insert overwrite table tb3 partition (day='${YYYYMMDD}')
select col1 , col2 from tb1
join tb2 on tb1.col1 = tb2.col1 
where tb11.day='20230101'
distribute by rand()

-- 处理表
drop table tb3;
set hive.merge.size.per.task=64000000;
create table tb3 as 
select * from dw.xxxxxxxxxxxxxxxx where day='20230722'
distribute by col;
 


--结果集
[node1]$ hdfs dfs -ls -h hdfs://马赛克/user/hive/warehouse/马赛克
Found 18 items
-rwxrwxrwx   3 bdp supergroup     62.4 M 2023-07-24 15:21 hdfs://马赛克/user/hive/warehouse/马赛克/000000_0
-rwxrwxrwx   3 bdp supergroup     62.4 M 2023-07-24 15:21 hdfs://马赛克/user/hive/warehouse/马赛克/000001_0
-rwxrwxrwx   3 bdp supergroup     62.4 M 2023-07-24 15:21 hdfs://马赛克/user/hive/warehouse/马赛克/000002_0
-rwxrwxrwx   3 bdp supergroup     62.4 M 2023-07-24 15:21 hdfs://马赛克/user/hive/warehouse/马赛克/000003_0
-rwxrwxrwx   3 bdp supergroup     62.4 M 2023-07-24 15:21 hdfs://马赛克/user/hive/warehouse/马赛克/000004_0

初步结论

就算是动态分配的spark服务跑hql也是可以做结果集的分片的

spark executor 和 map 数的关系

作业显示是65map和17executor的关系, 好像是1:4

有大佬和我讲解过原理,但我还是没记住.... : < 跟容器有关

思路3(扩展)

刚才设置的参数是64m左右一个,但是场景看起来并不是通用的

所以这个问题如果想要延时下去继续研究

其实就是要掌握这些map reduce参数 或者split或者分区参数应该设置的多大比较合适

比如分区表A的分区a内有2个文件块

大小分别是300 400 

实际hive 用spark mr的时候会自动切割,默认256一个

那么就会产生3个map

3个map那跑的特别慢比如说跑了80分钟,或者平均时间都很长,不满意

那这个时候,如果按照刚才的split参数设置 ,切32一个 

256/32= 8倍

那么就是80分钟/8 = 10分钟,理想效果是如此

不过这么做会非常消耗资源

其他自用的参数

set hive.execution.engine=spark;
set hive.execution.engine=mr;
--有时候spark跑不了的任务可以走mr跑,但是注意集群资源

set hive.spark.client.future.timeout=200;
set hive.spark.client.connect.timeout=80000ms;
--显而易见的参数


set spark.driver.memory=10.8g
set spark.yarn.driver.memoryOverhead=1.2g
-- driver 12g 

set spark.executor.memory=8.55g;
set spark.yarn.executor.memoryOverhead=1.51g 
-- executor 10g

set hive.exec.reducers.bytes.per.reducer=64000000; 
--控制reduce大小

set hive.merge.smallfiles.avgsize=16777216; --16m
--合并小文件


set spark.dynamicAllocation.cachedExecutorIdleTimeout
set  spark.dynamicAllocation.maxExecutors ;
set  spark.dynamicAllocation.minExecutors ;
set spark.dynamicAllocation.executorIdleTimeout ;
set hive.exec.orc.split.strategy;
-- 下面的试着没什么用的样子

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值