本文将介绍Hive调优的整体过程,以及本人对Hive调优过程的一些思考,包括Hive调优的一般步骤,和调优方法。
1,Hive一般优化方法
1,查看HiveSQL执行计划
Hive SQL的执行计划描绘SQL实际执行的整体轮廓,通过执行计划能了解SQL程序在转换成相应的计算引擎的执行逻辑,通过执行逻辑就能够更好的掌握程序出现的性能瓶颈点在哪,从而能够实现更有针对性的优化。
我们通过explain关键字查看下面语句的执行计划:
explain select age,count(1) from student_txt group by age;
MR引擎的执行计划如下:
STAGE DEPENDENCIES:
Stage-1 is a root stage
Stage-0 depends on stages: Stage-1
STAGE PLANS:
Stage: Stage-1
Map Reduce
Map Operator Tree:
TableScan
alias: student_txt
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: age (type: string)
outputColumnNames: age
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
Group By Operator
aggregations: count(1)
keys: age (type: string)
mode: hash
outputColumnNames: _col0, _col1
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
Reduce Output Operator
key expressions: _col0 (type: string)
sort order: +
Map-reduce partition columns: _col0 (type: string)
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
value expressions: _col1 (type: bigint)
Reduce Operator Tree:
Group By Operator
aggregations: count(VALUE._col0)
keys: KEY._col0 (type: string)
mode: mergepartial
outputColumnNames: _col0, _col1
Statistics: Num rows: 6100000 Data size: 610000000 Basic stats: COMPLETE Column stats: NONE
File Output Operator
compressed: false
Statistics: Num rows: 6100000 Data size: 610000000 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.SequenceFileInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
ListSink
Spark执行引擎的执行计划如下:
STAGE DEPENDENCIES:
Stage-1 is a root stage
Stage-0 depends on stages: Stage-1
STAGE PLANS:
Stage: Stage-1
Spark
Edges:
Reducer 2 <- Map 1 (GROUP, 37)
DagName: root_20200622221933_43f5ca02-fcc1-4a5e-9200-f244cc02d015:1
Vertices:
Map 1
Map Operator Tree:
TableScan
alias: student_txt
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
Select Operator
expressions: age (type: string)
outputColumnNames: age
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
Group By Operator
aggregations: count(1)
keys: age (type: string)
mode: hash
outputColumnNames: _col0, _col1
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
Reduce Output Operator
key expressions: _col0 (type: string)
sort order: +
Map-reduce partition columns: _col0 (type: string)
Statistics: Num rows: 12200000 Data size: 1220000000 Basic stats: COMPLETE Column stats: NONE
value expressions: _col1 (type: bigint)
Reducer 2
Execution mode: vectorized
Reduce Operator Tree:
Group By Operator
aggregations: count(VALUE._col0)
keys: KEY._col0 (type: string)
mode: mergepartial
outputColumnNames: _col0, _col1
Statistics: Num rows: 6100000 Data size: 610000000 Basic stats: COMPLETE Column stats: NONE
File Output Operator
compressed: false
Statistics: Num rows: 6100000 Data size: 610000000 Basic stats: COMPLETE Column stats: NONE
table:
input format: org.apache.hadoop.mapred.SequenceFileInputFormat
output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Stage: Stage-0
Fetch Operator
limit: -1
Processor Tree:
ListSink
对比mr执行引擎和spark执行引擎,两者的执行计划基本一致。
扩展:
修改以下配置可以切换hive执行引擎:
set hive.execution.engine=spark; //切换spark执行引擎
set hive.execution.engine=mr; //切换map-reduce执行引擎
2 使用yarn提供的日志
我们通过yarn日志可以知道HiveSQL所有阶段的运行信息,查看日志的连接,可以在每个作业执行后,在控制台打印的信息中心找到。
如图所示,Tracking URL就是我们需要的日志链接,复制链接在浏览器打开,将得到如下图所示页面:
此页面反映了SQL运行的整体情况,单击左边Job下的Counters链接,可以看到熟悉的信息,
这个页面描述里MapReduce作业在各个阶段的量化数据,例如,Map input records 表示Map阶段输入的数据条数,Map output bytes 表示Map阶段输出数据的字节数,Map output records 表示Map阶段 输出记录数,通过这些关键词,可以看到一个作业在运行中具体的,可以量化的数据描述。
3,hive调优的原则
- 理透需求,这是优化的根本
- 把我数据全链路,这是优化的脉络
- 坚持代码简介,这让优化更简单
- 没有瓶颈时谈优化,是自寻烦恼
4,Hive程序相关规范
1,开发规范
- 单条SQL长度不宜超过一屏
- SQL子查询嵌套不宜超过3层
- 避免SQL代码的复制粘贴,如果有多处逻辑一致的代码,可以将执行结果存储到临时表里。
- 尽可能使用SQL自带的高级命令。
- 使用set命令进行配置属性设置时,要写好注释。
代码里不允许对表/分区/列的DDL语句,除了新增和删除分区。 - 保持一个查询语句所处理的表类型单一。
- 关注NULL值 的数据处理。
- SQL表连接的条件列和查询的过滤的列最好要有分区列和分桶列。
- 存在多层嵌套,内层嵌套表的过滤条件不要写到外层,例如:
select a.*
from a
left join b
on a.id=b.id
where a.no=1
应该写为:
select a.*
from (select * from a where a.no=1) a
left join b
on a.id=b.id
2,设计规范
- 表结构要有注释。
- 列等属性字段需要有注释。
- 不要使用索引。索引在HIVE3.0后废除,使用物化视图或数据存储采用ORC格式可以代替索引功能。
- 创建内部表不允许指定数据存储路径。
- 创建非接口表,只允许使用ORC或者Parquet,同一个库内只运行使用一种数据存储格式。
- Hive适合处理宽表,适当冗余数据有助于Hive的处理性能。
- 表的文件块大小要与HDFS的数据块大小尽量相等。
- 善用分区分桶表。
3,命名规范
- 库/表/字段命名要自成一套体系:
- 表以tb_开头。
- 临时表以tmp_开头。
- 视图以v_开头。
- 自定义函数以udf_开头。
- 原始数据表所在的库以db_org_开头,明细数据所在库以db_detail_开头,数据仓库以db_dw_开头。