当前位置: 首页 > news >正文

Hive 调优

个人总结Hive调优分为两大类,参数调优和SQL调优

参数调优

0. 比较有用的参数

--设置用户使用队列
set mapreduce.job.queuename=root.paas_test;-- 设置作业名 
set mapred.job.name = HV_INS_ORDER_INFO_D(${hivevar:statis_date});--让CLI打印出字段名称
set hive.cli.print.header=true;

1. 控制map/reduce的内存和核数

这个参数有时候用的比较多,比如报oom,堆内存溢出等,数量过大,处理慢等可以适当增加这个值

set mapreduce.map.memory.mb=3072; 
set mapreduce.map.cpu.vcores=1; 
set mapreduce.reduce.memory.mb=6144; 
set mapreduce.reduce.cpu.vcores= 2 ;

2. 控制reduce个数的参数

--控制每个redcue处理量的参数
set hive.exec.reducers.bytes.per.reducer=1000000000;--控制单个job最大redcue个数
set hive.exec.reducers.max=2999;--直接指定单个job多少个reduce个数
set mapreduce.job.reduces=10;  --或者用老版本的set mapred.reduce.tasks

3. 控制map个数的参数,配合小文件治理一起使用

set mapred.max.split.size=256000000 ;  
set mapred.min.split.size=32000000 ;
set mapred.min.split.size.per.node=32000000 ;
set mapred.min.split.size.per.rack=32000000 ;

4. 小文件治理参数

--开启小文件合并,以及小文件大小
set  hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 
set  hive.merge.mapfiles = true ;
set  hive.merge.mapredfiles = true;
set  hive.merge.smallfiles.avgsize=32000000;
set  hive.merge.size.per.task=25600000;--控制map的输入大小,实现真正的小文件合并
set mapred.max.split.size=256000000 ;  
set mapred.min.split.size=32000000 ;
set mapred.min.split.size.per.node=32000000 ;
set mapred.min.split.size.per.rack=32000000 ;

5. 设置map/reduce的task实例的最大失败尝试次数

set  mapreduce.map.maxattempts=4;   --老版本用:mapred.map.max.attempts
set mapreduce.reduce.maxattempts =4;  ---老版本用 :mapred.reduce.max.attempts

6. 设置APPmaster的相关内存/CPU,使用相对较少,一般报appmaster内存溢出可以使用;

set yarn.app.mapreduce.am.resource.mb=6144;
set yarn.app.mapreduce.am.resource.cpu-vcores=2;
--补充即当 AppMaster 失败2次之后,运行的任务将会失败。 
Set mapreduce.am.max-attempts=2;(官方默认值)

7. 关于是否开启map/redduce 推测执行的参数,建议跟随集群层面即可

set mapreduce.map.speculative=true  ;
set mapreduce.reduce.speculative=true ;
set mapreduce.job.speculative.speculative-cap-running-tasks=0.1 ;

8. 对于需要并行执行的任务,开启并行

--是否开启job并行执行 ,默认false;
set hive.exec.parallel=true;--同一段sql最多可以并行执行多少作业job
set hive.exec.parallel.thread.number=8;

9. 动态分区相关参数

--(默认false),表示开启动态分区功能
set hive.exec.dynamic.partition =true;--默认strict模式,表示用户必须指定至少一个静态分区字段,以防用户覆盖所有分区。
--Nonstrict模式表示允许所有分区都可以直接动态分区;
set hive.exec.dynamic.partition.mode = nonstrict;--默认100,一般可以设置大一点,比如1000,表示每个maper或reducer可以允许创建的最大动态分区个数,超出则会报错   
set  hive.exec.max.dynamic.partitions.pernode=100;--表示一个动态分区语句可以创建的最大动态分区个数,超出报错   
set hive.exec.max.dynamic.partitions =1000;--(默认) 全局可以创建的最大文件个数,超出报错。
set hive.exec.max.created.files =10000;

10. mapjoin优化参数

将小表上传到分布式缓存,然后分发到大表各个maptask的节点

--mapjoin优化参数,注意mapjoin的使用场景;
set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize= 25000000;

11. groupby参数优化

--开启mapside聚合,建议开启
set hive.map.aggr=true;--负载均衡,慎用,尤其和上面参数一起使用时可能造成错误的统计结果
set  hive.groupby.skewindata= false;

12. 向量化默认,慎用,有时候会变慢;

set hive.vectorized.execution.enabled=true;

13. 了解即可,关于Hadoop2.x的jvm重用机制的uber模式

--是否启用uber功能
set mapreduce.job.ubertask.enable=false;
set mapreduce.job.ubertask.maxmap=9;
set mapreduce.job.ubertask.maxreduces=1;
set mapreduce.job.ubertask.maxbytes=dfs.block.size;

14. 本地模式

set hive.exec.mode.local.auto=true; 
set hive.exec.mode.local.auto.inputbytes.max=268217728;
set hive.exec.mode.local.auto.tasks.max=10;

15. 严格模式

set hive.mapred.mode=nonstrict;

16. fetch抓取模式

set hive.fetch.task.conversion=more;

17. limit限制

-- 官方默认false
set  hive.limit.optimize.enable=true;-使用limit做数据的子集查询时保证的最大行数据量
set hive.limit.row.max.size= 100000;--在使用limit做数据子集查询时,可抽样的最大文件数
set hive.limit.optimize.limit.file= 10;set hive.limit.optimize.fetch.max=50000;

18. 常用命令

--1.手动通过客户端杀死任务
yarn     application -kill  application_1639740855307_4111216
hadoop   job          -kill   job_1639740855307_4111216
hadoop job -kill-task attempt_1639740855307_4111291_r_000001_1--2.给在跑的任务换个队列跑
yarn  application -movetoqueue    application_1639740855307_3934397  -queue     root.ga_mid

19. 偶尔可能用的参数

--1.查询加个表头(特殊场景使用)set hive.cli.print.header=true;--2.给作业加个名称,统一名称,很香的set mapred.job.name='xxxxxx';--3.如果 DROP TABLE/VIEW/PARTITION/INDEX/TEMPORARY FUNCTION 指定了一个不存在的表/视图,不要报错set hive.exec.drop.ignorenonexistent=false;

20. 分桶表的使用

set hive.enfore.bucketing =true; 
set hive.enforce.sorting=true;
set hive.optimize.bucketingsorting=true;

21. 开启smb-mapjoin

单纯适合数据量大的情况,对于数据倾斜的优化有限

set hive.optimize.bucketmapjoin = true;
set hive.auto.convert.sortmerge.join=true;
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
set hive.optimize.bucketmapjoin.sortedmerge = true;

22. skewedjoin数据倾斜优化

只适合inner join,而且和parallel一起用会丢数据,少用,可以手写

set hive.optimize.skewjoin=true;
set  hive.skewjoin.key =5000000;

23. 修复分区表

--修复分区
MSCK [REPAIR] TABLE table_name [ADD/DROP/SYNC PARTITIONS];
msck repair table s_test.ods_star_sample_data_a_d;---分区表加字段
alter table default.testparquet add columns(c8 string) cascade;

24. 运维相关,稍微了解一下

--1.表示maptask至少完成50%以上,才开始为reduce申请资源吗,执行reducetask。实际比比如我们公司生产设置的1。
set mapreduce.job.reduce.slowstart.completedmaps=0.5 ;---2.把一台物理机的多少资源分配给Nodemanager,比如64core/256G的机器,我们分配给nm 48core/195G
set yarn.nodemanager.resource.memory-mb=195*1024*1024*1024
set yarn.nodemanager.resource.cpu-vcores=48---3.给每个container分配的内存范围,CPU范围
yarn.scheduler.minimum-allocation-mb=3072;
yarn.scheduler.maximum-allocation-mb=64*1024;
yarn.scheduler.minimum-allocation-vcores=1;
yarn.scheduler.maximum-allocation-vcores=32;---4.严格模式开启
set hive.mapred.mode=strict;

SQL调优

SQL调优也可以分成三部分,过滤调优,聚合调优,join调优

过滤调优

尤其要关注的是过滤条件使用的位置,个人总结是这样的:

  1. inner join 放在哪都一样
  2. left/right join 主表条件放在where中,从表条件放在on中
  3. full join 放在哪都不生效,建议使用子查询

分区裁剪

注意分区裁剪是发生在map之前的。

列裁剪

最好是和列存储格式配合使用,比如orc,parquet。

就是避免select * 这种情况。

注意,列裁剪不会减少开始时候的map数量,但是会减少中间和结果的数据量。

谓词下推

就是条件写在where 和 on 里有什么区别。能过滤的先过滤,就是这样。

聚合优化

count(distinct xxx)

为了保证全局的一致性,count(distinct xxx)只会启用一个reduce来执行,对于数据量特别大的情况下的话,就会很慢。这时候我们就可以采用预聚合的方式来环境最好reduce的压力(group by + count)

order by

为了保证全局的一致性,order by也只会启用一个reduce来执行。

在严格模式下,order by 必须加limit限制

对于order by 我们通过使用子查询,在每个 Reduce 中进行排序后,各自取得前 N 个数据,然后再对结果集进行全局排序,最终取得结果。

--没有优化版本,全局排序跑的很慢
SELECTt2.dept_nm,t1.db ,table_name ,SUM(t1.filesize_mb)/1024.0 as filesize_gb
FROM mobdi_test.tmp_fsimage_info_log_clean_result t1
LEFT JOIN _bg_devops.dept_db_relationships t2
ON t1.db =t2.db_nmmob
WHERE t1.stat_day ='20230221'AND t1.modificationtime < '2022-04-25'AND t1.accesstime < '2022-04-25'
GROUP BYt2.dept_nm,t1.db ,table_name
ORDER BY filesize_gb desc LIMIT 100;
--优化版本:通过使用子查询,在每个 Reduce 中进行排序后,各自取得前 N 个数据,然后再对结果集进行全局排序,最终取得结果。
SELECTdept_nm,db,table_name,filesize_gb
FROM
(selectdept_nm,db,table_name,filesize_gbfrom( SELECTt2.dept_nm,t1.db ,table_name ,SUM(t1.filesize_mb)/1024.0 as filesize_gbFROM mobdi_test.tmp_fsimage_info_log_clean_result t1LEFT JOIN mob_bg_devops.dept_db_relationships t2ON t1.db =t2.db_nmWHERE t1.stat_day ='20230221'AND t1.modificationtime < '2022-04-25'AND t1.accesstime < '2022-04-25'GROUP BYt2.dept_nm,t1.db ,table_name
)T1
distribute by filesize_gb sort by filesize_gb desc limit 100 ) T2
ORDER BY filesize_gb LIMIT 100;

Multiple Inserts

使用多插入(Multiple Inserts)语法也叫 多表 插入 (Multi Table Insert)。多插入(Multiple Inserts)将扫表次 数降 低到 最小 ,降低插入总耗时。之所以说是总耗时,其实并没有降低写入的数据量或者降低写入时间,而是降低扫表时间,将多次扫表合并为一次扫表。

Hive 官网给出通过查询 insert 表的语法格式:
Standard syntax:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1,
partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)]
select_statement1 FROM from_statement;-- Hive extension (multiple inserts):
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1,
partcol2=val2 ...) [IF NOT EXISTS]] select_statement1
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]]
select_statement2]
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...;
FROM from_statement
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1,
partcol2=val2 ...)] select_statement1
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2]
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]]
select_statement2] ...;-- Hive extension (dynamic partition inserts):
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1],
partcol2[=val2] ...) select_statement FROM from_statement;
INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...)
select_statement FROM from_statement;

知识点 1:从 Hive 0.13.0 开始,可以通过使用 TBLPROPERTIES (“immutable”=“true”)创建表来使其不可变。默认值为“不可变”=“假”。如果任
何数据已经存在,则 INSERT INTO 行为将被禁止到不可变表中,但如果不可变表为空,则 INSERT INTO 仍然有效。INSERT OVERWRITE 的行为不受“不可变”表属性的影响。

join的优化

对于join的优化,主要就是为了避免shuffle。

http://www.dtcms.com/a/395446.html

相关文章:

  • 王晨辉:RWA注册登记平台赋能资产数字化转型
  • 周末荐读:美 SEC 推出加密货币 ETF 上市标准,Base 发币在即
  • HTTP API获取 MQTT上报数据
  • Apache HTTP基于端口的多站点部署完整教程
  • 新网站如何让百度快速收录的方法大全
  • 企业非结构化数据治理与存储架构优化实践探索
  • dagger.js 实现嵌套路由导航:对比 React Router 的另一种思路
  • React自定义同步状态Hook
  • 系统架构设计能力
  • 安卓图形系统架构
  • 《ZooKeeper终极指南》
  • 软考 系统架构设计师系列知识点之杂项集萃(154)
  • 算法提升之单调数据结构-单调栈与单调队列
  • 【Linux】初识进程(Ⅰ)
  • VMware登录后没有网络解决方法
  • Infoseek助力品牌公关升级:从成本中心到价值引擎
  • AR 运维系统与 MES、EMA、IoT 系统的融合架构与实践
  • 牛客周赛 Round 110
  • AutoMQ x Lightstreamer: Kafka 金融数据实时分发新方案
  • Vulkan原理到底学什么
  • 第14讲 机器学习的数据结构
  • MATLAB的宽频带频谱感知算法仿真
  • Adobe Fresco下载教程Adobe Fresco 2025保姆级安装步骤(附安装包)
  • MQTT 服务质量 (QoS) 深度解析
  • MySQL EXPLAIN 中的七种 type 类型详解
  • NestJS认识
  • 6.MySQL索引的数据结构【面试题】
  • 【vLLM 最新版v0.10.2】docker运行openai服务与GGUF量化使用方式
  • 鸿蒙开发入门:ArkTS基础与实战
  • #C语言——刷题攻略:牛客编程入门训练(十三):一维数组(二),轻松拿捏!