Hadoop之Hive(调优篇)
Posted _TIM_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop之Hive(调优篇)相关的知识,希望对你有一定的参考价值。
Hive调优
Fetch抓取
Hive
中对某些情况的查询可以不必使用MapReduce
计算。例如:SELECT * FROM score;
在这种情况下,Hive
可以简单地读取score
对应的存储目录下的文件,然后输出查询结果到控制台。通过设置hive.fetch.task.conversion
参数,可以控制查询语句是否走MapReduce
.
本地模式
大多数的Hadoop Job
是需要Hadoop
提供的完整的可扩展性来处理大数据集的。不过,有时Hive的输入数据量是非常小的。在这种情况下,为查询触发执行任务时消耗可能会比实际job
的执行时间要多的多。对于大多数这种情况,Hive
可以通过本地模式在单台机器上处理所有的任务。对于小数据集,执行时间可以明显被缩短。用户可以通过设置hive.exec.mode.local.auto
的值为true
,来让Hive
在适当的时候自动启动这个优化。
MapJoin
如果不指定MapJoin
或者不符合MapJoin
的条件,那么Hive
解析器会在Reduce
阶段完成join
,容易发生数据倾斜。可以用MapJoin
把小表全部加载到内存在map
端进行join
,避免reducer
处理。
Group By
默认情况下,Map
阶段同一Key
数据分发给一个reduce
,当一个key
数据过大时就倾斜了。并不是所有的聚合操作都需要在Reduce
端完成,很多聚合操作都可以先在Map
端进行部分聚合,最后在Reduce
端得出最终结果。有数据倾斜的时候进行负载均衡set hive.groupby.skewindata = true;
当选项设定为true
,生成的查询计划会有两个MR Job
。
- 第一个
MR Job
中,Map
的输出结果会随机分布到Reduce
中,每个Reduce
做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key
有可能被分发到不同的Reduce
中,从而达到负载均衡的目的; - 第二个
MR Job
再根据预处理的数据结果按照Group By Key
分布到Reduce
中(这个过程可以保证相同的Group By Key
被分布到同一个Reduce
中),最后完成最终的聚合操作。
Count(distinct)
数据量小的时候无所谓,数据量大的情况下,由于COUNT DISTINCT
操作需要用一个ReduceTask
来完成,这一个Reduce
需要处理的数据量太大,就会导致整个Job
很难完成,一般COUNTDISTINCT
使用先GROUP BY
再COUNT
的方式替换:
笛卡尔积
尽量避免笛卡尔积,即避免join
的时候不加on
条件,或者无效的on
条件,Hive
只能使用1个reducer
来完成笛卡尔积。
动态分区调整
往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区。
并行执行
Hive
会将一个查询转化成一个或者多个阶段。这样的阶段可以是MapReduce
阶段、抽样阶段、合并阶段、limit
阶段。或者Hive
执行过程中可能需要的其他阶段。默认情况下,Hive
一次只会执行一个阶段。不过,某个特定的job
可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整个job
的执行时间缩短。不过,如果有更多的阶段可以并行执行,那么job
可能就越快完成。
此外,还有严格模式、JVM重用、推测执行等调优方法
以上是关于Hadoop之Hive(调优篇)的主要内容,如果未能解决你的问题,请参考以下文章