Hive的优化

Posted 蓝小冰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive的优化相关的知识,希望对你有一定的参考价值。

# Hive的计算和存储

hive的计算完全依赖于MapReduce!

hive的存储完全依赖于HDFS

# Hive什么情况下可以避免进行MapReduce

1.本地模式下,即没有使用复合函数(count,sum,avg等)

    select uid,pid from sogou_uid_pid limit 10;

2.查询语句中的过滤条件是分区字段的情况下不会执行MapReduce。

# Hive的数据倾斜

数据倾斜的表现:大部分的reduce任务已经完成,少数的reduce一直停留在某个百分比不动。
数据倾斜的原因:  

1).null值过多

2).key值分布不均匀

3).业务数据本身的问题

4).建表时考虑不周

解决办法:

会在下面的优化中详细的解释

# Hive的优化

## 0.使用explain

hive > explain select count(uid) from tmall_201412;

查询语句本身并不会被执行,他会以语法树的形式将执行过程展现出来。

## 1.join优化

如果join中的多个表的join key是同一个,则join会被转换为单个的map/reduce任务:

join时,Hive会缓存join序列中除了最后一个表的所有记录,在通过最后一个表将结果序列化到文件系统,这一实现有助于reduce端减少内存的使用量。生产中,应该把最大的表写在最后(否则会因为缓存浪费大量的内存)

## 2.本地模式

大多数的Hadoop的job需要Hadoop提供的完整的可扩展性来处理大数据集。不过有时候Hive的输入数据量是非常小的。在这样的情况下,查询也需要很长的时间才能完成。在大多数的情况下,Hive可以通过本地模式在单台机器上(或者某些时候在单个进程中)处理所有的任务。对于小数据集的执行时间会明显的缩短。
可以通过以下的命令,临时启动本地模式:

set oldjobtracker=${hiveconf:mapred.job.tracker};

set mapred.job.tracker=local;

set mapred.tmp.dir=/home/username/tmp;

set mapred.job.tracker=${oldjobtracker};

也可以通过修改配置文件(hive-site.xml),让Hive在适当的时候启动本地模式:
        <property>
            <name>hive.exec.mode.local.auto</name>
            <value>true</value>
            <description>
                let hive determine whether to run in local mode automatically
            </description>
        </property>

## 3.limit

limit语句我们也经常用到,不过,在很多情况下limit语句还是需要执行整个查询语句,然后返回部分结果。因为这种情况通常是浪费的,所以我们应该尽量的避免这样的情况。我们可以通过Hive的配置文件来控制,当使用limit语句时,对数据源进行抽样:
            <property>
                <name>hive.limit.optimize.enable</name>
                <value>true</value>
                <description>Wheather to enable to optimization to try a smaller subset of data for simple limit first . </description>
            </property>

当我们设置了hive.limit.optimize.enable的值为true,还有两个参数可以控制这个操作,hive.limit.row.max.size和hive.limit.optimize.limit.file:
            <property>
                <name>hive.limit.row.max.size</name>
                <value>100000</value>
                <description>
                     when trying a smaller subset of data for simple limit ,how much size we need to guarantee each row to hive at least.
                </description>
            </property>

             <property>
                <name>hive.limit.optimize.limit.file</name>
                <value>10</value>
                <description>
                    when trying a smaller subset if data for sumple limit,maximum number if files we can sample.
                </description>
            </property>

使用limit的优缺点:

缺点:有些需要的数据可能永远不会被处理到,

缺陷:有些数据始终得不到使用。

## 4.并行执行

Hive会将一个查询转换成一个或者多个stage。默认情况下,Hive一次只会执行一个stage。但是在某些job中可能包含众多的stage,而这些stage可能并非完全互相依赖,也就是说某些stage可以并行执行,这样可以使整个job的执行时间缩短,若很多stage都可以并行执行,那么集群的利用率就会增加,job的执行速度也会更快点。

我们可以通过配置文件,来开启并行执行
        <property>
            <name>hive.exec.parallel</name>
            <value>true</value>
            <description>
                whether to execute jobs in parallel 
            </description>
        </property>

## 5.严格模式

Hive提供了一个严格模式,以防止用户进行一些意想不到的不好的查询:

1).分区表查询的时候,没有where条件,不允许扫描所有的分区;

2).使用order by,必须使用limit 限制,可以防止reduce额外执行时间;

3).笛卡尔积,查询条件必须使用on 不能使用where替代。

## 6.JVM重用

MapReduce会将一个job转换成多个task。默认情况下,每一个task对应一个新的JVM实例,都需要开启和销毁的开销。对于小文件,每个文件都对应一个task。在一些情况下,JVM的开启和销毁可能会比实际处理数据的时间消耗要长!

JVM调优是Hadoop调优参数的内容,其对Hive的性能具有非常大的影响,特别是对于很难避免小文件的场景或者task特别多的场景,这类场景大多数的执行时间都很短。

Hadoop的默认配置通常是使用派生JVM来执行map和reduce任务。这时JVM的启动过程可能造成相当大的开销,尤其是执行的job包含成百上千个task任务的情况。JVM重用可以使得JVM实例在同一个job中重新使用N次。N的值可以在Hadoop的mapred-site.xml文件中设置:
        <property>
            <name>mapred.job.reuse.jvm.num.tasks</name>
            <value>10</value>
            <description>
                how many tasks to run per jvm. if set to -1 there is no limit.
            </description>
        </property>

缺点:开启JVM便会一直占用task插槽,以便进行重用,直到任务完成后才释放。如果某个后者某几个reduce任务执行时间比其他的reduce时间长的多的话,保留的插槽就会一直处于空闲的状态,无法被其他job使用,直到所有task都结束才会释放。

##  7.调整map和reduce的个数

Hive通过将查询划分成一个或者多个MapReduce任务达到并行执行的目的。每个任务都可能有多个mapper和reducer任务,其中至少有一些是可以并行执行的。

如果太多的mapper和reducer任务,就会导致启动阶段、调度和运行job过程产生过多的开销;若设置的数据量太少,就可能没有充分的利用集群内在的并行性。所以要根据具体的查询调整reduce的数目。

Hive是按照输入数据量大小来确定reducer个数的。我们可以通过dfs -count 命令来计算输入量的大小,这个命令和Linux中的du -s类似;用于计算指定目录下所有数据的总大小:
        hdfs dfs -ls /cars 
        1            1           20671380 /cars
        du -s ./data50W.dat 
        64772    ./data50W.dat

属性hive.exec.reducers.bytes.per.reducer的默认值是1GB。若Hive操作的输入数据量经过map之后产生了很大的数据量,这时reduce的数量计算就会影响执行,可以根据实际情况来动态的调整reduce处理的数据量。集群默认的reducer的个数为3个。

## 8.动态分区调整

可以调整动态分区插入允许的分区数。虽然太多的分区可能产生过多的小文件,造成NameNode负荷变重,但是还是将其设置大以便查询。

通过修改hive-site.xml调整:

设置动态分区的模式
    <property>
        <name>hive.exec.dynamic.partition.mode</name>
        <value>strict</value>
        <description>
            in strict mode ,the user must specify at least one static partition in case the user accidentally overwrites all partitions . 
        </description>
    </property>

 <property>
        <name>hive.exec.max.dynamic.partitions</name>
        <value>300000</value>
        <description>
            maximum number of dynamic partitions allowed to be created in total .
        </description>
    </property>

设置最大的动态分区数
    <property>
        <name>hive.exec.max.dynamic.partitions.pernode</name>
        <value>10000</value>
        <description>
            maxmum number of dynamic partitions allowed to be created in each mapper/reducer node.
        </description>
    </property>

## 9.map端的聚合以及muti-group by

事实上并不是所有的聚合操作都需要在reduce部分进行,很多聚合操作都可以先在map端进行部分的聚合,然后在reduce端得到最终结果。

## 10.推测执行

推测执行是Hadoop中的一个功能,可以触发执行一些重复的task。目标的通过加快获取单个task的结果以及进行侦测将执行慢的TaskTracker加入黑名单的方式来提高整体的任务执行效率。

若运行时的偏差非常敏感的话,那么可以将这些功能关掉,若输入的数据量很大,并且需要执行长时间的map或者reduce task的话,那么启动推测执行造成的浪费是非常大的。

Hive本身也提供了配置项来控制reduce-side的推测执行:
    <property>
        <name>hive.mapred.reduce.tasks.speculative.execution</name>
        <value>true</value>
        <description>
            whether speculative execution for reducers should ve turned on.
        </description>
    </property>
## 11.压缩

减少数据的传输,达到加快速度的目的

以上是关于Hive的优化的主要内容,如果未能解决你的问题,请参考以下文章

hive优化方法

Hive与优化方法

Hive与优化方法

Hive与优化方法

Hive优化

hive高级操作(优化,数据倾斜优化)