Hive入门 优化总结
Posted 杀智勇双全杀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive入门 优化总结相关的知识,希望对你有一定的参考价值。
Hive入门(八) 优化总结
之前有写过这篇稿子。。。其它稿子中也零散写过一些相关内容,特意总结下,方便用到的时候查找。
属性优化(配置优化)
本地模式
Job的输入数据大小<128M(hive.exec.mode.local.auto.inputbytes.max(默认128MB)配置),
Job的map数<4个(hive.exec.mode.local.auto.tasks.max(默认4)个)、Job的reduce数为0或者1的小任务才能使用。本地模式本机运行(不提交给YARN和集群)小任务更快。
hive.exec.mode.local.auto=true;
JVM重用
开启后不会频繁占用、释放堆内存,节省堆内存资源调度时间。
mapreduce.job.jvm.numtasks=10;
推测执行
个别Task卡壳时会启动另一个Task执行同样的操作,后完成的Task会被Kill。
mapreduce.map.speculative=true;
mapreduce.reduce.speculative=true;
hive.mapred.reduce.tasks.speculative.execution=true;
Fetch抓取
对小表、少量字段查询时,完全没必要走MapReduce,Hive中自带了SQL引擎可以执行这种轻量级任务。
hive.fetch.task.conversion=more;
并行执行
hive.exec.parallel=true;
hive.exec.parallel.thread.number=16;
压缩
hive.exec.compress.intermediate=true;
hive.exec.orc.compression.strategy=COMPRESSION;
mapreduce.map.output.compress=true;
mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.DefaultCodec;
矢量化查询
hive.vectorized.execution.enable=true;
hive.vectorized.execution.reduce.enable=true;
零拷贝
hive.exec.orc.zerocopy=true;
关联优化
hive.optimize.correlation=true;
CBO优化器
hive.cbo.enable=true;
hive.compute.query.using.stats=true;
hive.stats.fetch.column.stats=true;
hive.stats.fetch.partition.stats=true;
小文件处理
设置Hive底层MapReduce读取数据的输入类,将所有文件合并为一个大文件作为输入:
hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
只有MapTask可以将MapTask产生的所有小文件进行合并:
hive.merge.mapfiles=true;
hive.merge.mapredfiles=true;
hive.merge.size.per.task=256000000;
hive.merge.smallfiles.avgsize=16000000;
索引优化
hive.optimize.index.filter=true;
谓词下推
谓词下推 这位大神写的很好。
谓词下推规则这位大神写的挺详细。
冒昧扒个图:
hive.optimize.ppd=true;
Inner Join和Full outer Join的条件写在on后边,还是where后边性能没区别。
Left outer Join时,右侧的表写在on后边,左侧的表写在where后边,性能更好。
Right outer Join时,左侧的表写在on后边,右侧的表写在where后边,性能更好。
SQL中出现不确定结果的函数无法实现谓词下推。
Map Join
hive.auto.convert.join=true;
hive.auto.convert.join.noconditionaltask.size=512000000;
Bucket Join
hive.optimize.bucketmapjoin=true;
hive.auto.convert.sortmerge.join=true;
hive.optimize.bucketmapjoin.sortedmerge=true;
hive.auto.convert.sortmerge.join.noconditionaltask=true;
Task内存
mapreduce.map.java.opts=-Xmx6000m;
mapreduce.map.memory.mb=6096;
mapreduce.reduce.java.opts=-Xmx6000m;
mapreduce.reduce.memory.mb=6096;
缓冲区大小
mapreduce.task.io.sort.mb=100;
Spill阈值
mapreduce.map.sort.spill.percent=0.8;
Merge线程
mapreduce.task.io.sort.factor=10;
Reduce拉取并行度
mapreduce.reduce.shuffle.parallelcopies=8;
mapreduce.reduce.shuffle.read.timeout=180000;
SQL优化
核心思想:先过滤后处理。在where或者join on等阶段就尽量把多余的数据过滤掉,避免这些无用的数据参与运算影响性能。
设计优化
分区表
减少MapReduce输入,在源头处减少数据量(过滤也需要比较,会影响性能)。
分桶表
减少比较次数,实现数据分类。将大数据拆分成桶表,构建Map Join。
文件存储
优先选用列式存储(常用parquet和ORC,但是ORC比较吃内存,parquet比较均衡)。
内存不足的优化
Hive底层是MapReduce,经常因为内存不够导致任务失败(Job History可以看到失败的原因)。
堆内存不足
会看到Error:Java heap space,需要给Task进程分配更多内存。
物理内存不足
类似6.0 GB of 6GB physical memoryused
就是内存全部用完。需要+/换内存条。代码层面可以基于分区处理,避免走Map Join。
虚拟内存不足
virtual memory used附近就是虚拟内存占用情况。由于虚拟内存占用的是硬盘空间,将默认的虚拟内存比例(2.1)调大。
数据倾斜的优化
运行程序时,某Task一直在运行,其它Task都结束,进度卡99%或者100%(也不出现进度回退的情况)。这种情况一般不是MapTask导致的(MapTask默认按128M的spill处理数据,个数多,相对负载均衡),大概率是ReduceTask数据分配不均衡(为了让相同K2交由同一个ReduceTask处理,默认根据K2的Hash取余确认交由哪个ReduceTask处理,指定了>1个ReduceTask时就可能有数据倾斜)。
group by/count(distinct)出现数据倾斜
开启Combiner
hive.map.aggr=true;
使用随机分区
hive.groupby.skewindata=true;
开启后底层自动走2个MapReduce,第一个随机分区,第二个对第一个的结果再次处理(做最终聚合)。
也可以手动指定:
SELECT * FROM table1 distribute by rand();
Join中产生数据倾斜
尽量避免走Reduce Join
在Map Join阶段将不需要参加Join的数据过滤,或者构建分桶表(将大表转化为小表)。
使用skewjoin
开启运行过程中skewjoin:
set hive.optimize.skewjoin=true;
如果这个key的出现的次数超过这个范围:
set hive.skewjoin.key=100000;
在编译时判断是否会产生数据倾斜:
set hive.optimize.skewjoin.compiletime=true;
不合并,提升性能:
set hive.optimize.union.remove=true;
如果Hive的底层走的是MapReduce,必须开启这个属性,才能实现不合并:
set mapreduce.input.fileinputformat.input.dir.recursive=true;
以上是关于Hive入门 优化总结的主要内容,如果未能解决你的问题,请参考以下文章