小言_互联网的博客

Hive入门(八) 优化总结

464人阅读  评论(0)

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;

转载:https://blog.csdn.net/qq_41990268/article/details/117080110
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场