备注:
Hive 版本 2.1.1
Hive的编译器将HQL转换成一组操作符(Operator)
操作符是Hive的最小处理单元
每个操作符代表一道HDFS操作或者MR Job 作业
Hive编译器
Parser:
将SQL转换成抽象语法树
语法解析器:
将抽象语法树转换成查询块
逻辑计划生成器:
将查询块转换成逻辑计划
物理计划生成器:
将逻辑计划转换成物理计划
物理计划优化器:
物理计划优化策略
利用Explain查看执行计划
语法:
:EXPLAIN [EXTENDED] query
输出:
优化的目的:提升查询性能,快速产出结果
Hive的优化思路:
列存储,高压缩比,列剪枝,过滤无用字段IO
压缩格式选择:snappy
并行执行
Hive产生的MR Job默认是顺序执行的,如果Job之间无依赖可以并行执行
set hive.exec.parallel=true;
本地执行
虽然Hive能够利用MR处理大规模数据,但某些场景下处理的数据量非常小可以本地执行,不必提交集群
set hive.exec.mode.local.auto=true;
hive.exec.mode.local.auto.inputbytes.max(默认128MB)
hive.exec.mode.local.auto.input.files.max(默认4)
合并输入小文件
如果Job输入有很多小文件,造成Map数太多,影响效率
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
合并输出小文件
set hive.merge.mapfiles=true; // map only job结束时合并小文件
set hive.merge.mapredfiles=true; // 合并reduce输出的小文件
set hive.merge.smallfiles.avgsize=256000000; //当输出文件平均大小小于该值,启动新job合并文件
set hive.merge.size.per.task=64000000; //合并之后的每个文件大小
控制Map/Reduce数
控制Map/Reduce数来控制Job执行的并行度
Num_Map_tasks= $inputsize/ max($mapred.min.split.size, min($dfs.block.size, $mapred.max.split.size))
Num_Reduce_tasks= min($hive.exec.reducers.max, $inputsize/$hive.exec.reducers.bytes.per.reducer)
JVM重用
JVM重利用可以使job长时间保留slot,直到作业结束
set mapred.job.reuse.jvm.num.tasks=10 //每个jvm运行10个task
推测执行
set hive.mapred.reduce.tasks.speculative.execution=true
set mapreduce.map.speculative=true
set mapreduce.reduce.speculative=true
一定要开启压缩
中间结果压缩,减少Job跟Job之间的IO开销
set hive.exec.compress.intermediate=true
set mapred.map.output.compression.codec=
最终结果压缩,减少存储空间
set hive.exec.compress.output=true
Set mapred.output.compression.codec=
Hive的Join类型:
方式一(自动判断):
set.hive.auto.convert.join=true;
hive.mapjoin.smalltable.filesize // 默认值是25mb, 小表小于25mb自动启动mapjoin
方式二(手动显式):
select /+mapjoin(A)/ f.a,f.bfrom A t join B f on (f.a=t.a)
使用方式:
hive.optimize.bucketmapjoin= true
和mapjoin一起工作,所有要Join的表都必须对Join key做了分桶,并且大表的桶数是小表的整数倍
由于对表设计有太多的限制,不太常用
数据倾斜是指由于数据分布不均匀,个别值集中占据大部分数据量,导致某一个或者几个ReduceTask处理的数据量相对很大造成的Job运行非常慢,甚至OOM挂掉
在SQL上,一般是由于group by 或者join shuffle key丌均匀造成的
数据倾斜是业务数据问题导致的,如果从业务上下手避免是最好的
Hive自身的优化方案:
hive.map.aggr=true //做map端预聚合,相当于Map端Combiner
hive.groupby.skewindata//将key的数据随机分发到Reduce端做聚合,然后再起一个Job对上一步的结果做聚合
set hive.optimize.skewjoin= true
set hive.skewjoin.key= 100000
// 超过阈值就判断为skew key
hive-site.xml中更改默认配置
在脚本中set变量
Hive的优化配置非常多,具体情况具体分析