欢迎投稿

今日深度:

hive 优化,

hive 优化,


.Sql 优化:

1. 根据不同的业务场景进行sql优化

2. 去除查询过程中不需要的 column

3. Where 条件判断再 tablescan 阶段就进行过滤

4. 利用partition信息 获取有效的数据信息

5. Map端的jion 以大表做驱动 小表加入内存当中

6. 调整jion的顺序 进来使 大表作为驱动表。

7. 对数据分布不均匀的表进行group by 时, 为了避免 数据集中到 reduce  可以分成两个阶段来执行 第一阶段利用distionct 第二阶段 再进行group by 。 

二.平台方面的优化

hive on tez

Hive spark

通过使用其他的计算引擎框架

.整体架构方面的优化

 现阶段 hive的整体架构 不紧可以支持 MapReduces 并且支持 Tez ,Spark 等计算引擎。

整体架构优化

1.  可以根据不同的业务场景 对表进行 分区 和动态分区

2.  问了了减少IO 可以对表进行压缩

3.  中间临时的小表都可以进行压缩设置

4. hive中间表以 SequenceFile保存,可以节约序列化和反序列化 的时间。

四.编写MapReduce

具体实例:

现象:

1.目前每日load出来的问题sql,最终的结果文件里面很多都只有一条数据。

2.资源影响巨大,对照脚本统计出来的sql运行时间,手动执行sql的时间是其十分之一到三分之一。

3.不少sql执行时的map数量能达到1000-3000,但是reduce数量在1左右。

由于每天load出的excle文档,zhrl租户的sql过长,手动无法执行,其它租户的sql抽取时又存在乱码问题,仅针对了zhrl_b租户的sql进行了分析,但是问题和优化可通用。

首先mapreduce中map数量是无法直接控制的,所以只能通过对map数量的影响因素方面进行调整,从而间接影响hive sql执行时map的数量。

 目前我们集群的情况:

(set) mapred.max.split.size=256000000   -------决定每个map处理的最大文件大小,B

(set) mapred.min.split.size.per.node=1    -------节点处理的最小文件大小

(set) mapred.min.split.size.per.rack=1     ------机架中可以处理的最小文件大小

(set) mapred.reduce.tasks=-1            ------设置reduce数量,这里-1也就是自动计算出需要reduce的个数

(set) hive.exec.reducers.bytes.per.reducer=256000000---------每个reduce处理的数据量

(set) hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat---------map端做combiner操作

(set) hive.merge.mapredfiles=true        ---------小文件合并

(set) hive.exec.reducers.bytes.per.reducer=256000000------控制一个job当中会有多少个reduce来处理,依据的是输入文件的总大小

set) hive.exec.reducers.max=1009    ----------控制最大reduce数量

 调整影响:

设置map,可能带来集群之间的io,因为可能涉及到文件的合并;设置reduce,则会对最后的结果文件个数造成直接影响;reduce太少,会导致reduce端的数据量太大,影响执行效率,导致整个job都不能结束;reduce太小,则会产生大量的结果文件,合并代价大,占用namenode的内存空间。

逻辑:

根据mapred.max.split.size来确认需要启动多少个map数。

比如文件大小260M,280M,则会启动两个map,剩余的4M,24M先做保留。

再根据mapred.min.split.size.per.node来针对剩下的文件做操作,如果设置为1,则表示剩余的文件自己启动一个map,这里会启动2两个;如果设置为28*1024*1024,则文件会合并成一个,启动一个map。但是正常情况下,不可能正好设置成28*1024*1024,也就是说,还是会产生剩余的文件。

最后根据mapred.min.split.size.per.rack,来决定是否要进行合并,对再次剩余的文件独自产生一个map。

 因此针对控制map数量和reduce数量:

针对map数量:

set mapred.max.split.size=

set mapred.min.split.size.per.node=

set mapred.min.split.size.per.rack=

针对reduce数量:

set mapred.reduce.tasks=

set hive.exec.reducers.bytes.per.reducer=

 优化手段:

1.针对那些map数量达到1000-3000的sql,可以通过设置mapred.max.split.size临时参数来减少map数量,目前测试的结果显示1000-2000map数量的sql,设置在512M,2000-3000map数量的设置在1G,运行时间有明显减少

 2.count(distinct xxx)语句的改写

比如:

insert into table lzl2 partition(date_dt = '2018-02-03') select 'test_xx' ,count(distinct bal_item_id) from test_xx

这个sql执行时间是57分钟,map数量367,reduce数量1。

时间如此之长的分析:

Mapreduce过程中,理论上map阶段会进行combine操作对输出结果做合并消重,以减少reduce阶段的数据量。但是如果使用了distinct,就会发生map阶段无法进行combine操作,对统计大量数据时,会导致最终map的全部输出由单个reduce task来处理,也就是说这个唯一的reduce task需要shuffle大量的数据,并且要进行排序聚合等处理,会导致map过程可能十几秒就完成,但是reduce过程需要长达30-50分钟。

直接增加reduce数量,set mapred.reduce.tasks=10;但是在执行过程中,发现reduce数量不管怎么改,实际运行时都是1。

这是因为hive在处理count这种全聚合操作时,会忽略掉用户指定的reduce task数量,而强制使用1,这样会造成单一的reduce task瓶颈。

改写成:

insert into table lzl2 partition(date_dt = '2018-02-03') select 'test_xx' ,t.b from (select count(*) as b from (select distinct bal_item_id from test_xx) a) 

第一阶段:map数量358,reduce数量485

第二阶段:map数量179,reduce数量1

总执行时长117秒。

分析:

这样改写的sql在执行时,会被分成两个job。

第一阶段job是选出全部的非重复bal_item_id,虽然在这阶段由于distinct对map阶段的combine产生了抑制,但是可以通过调整reduce的数量来提高这阶段shuffle效率,这里我进行了两种对比,set mapred.reduce.tasks=-1和set mapred.reduce.tasks=

10,前者表示让mr自己去计算需要启动多少个reduce,后者认为设置,由于无法相对准备的给出reduce的数量,所以后者的效率还是不算高,因此选择了默认配置set mapred.reduce.tasks=-1。

PS:默认设置很省事,但是绝不是最佳,前期优化可以这样选择。

 第二阶段job,进行count(*),虽然这阶段强制指定了reduce task,但是由于第一阶段的job已经对数据进行合并去重的操作,这阶段的map只需输出一个合并后的计数即可,因此较少的map输出不会成为单一reduce task的瓶颈。

 Jion 数据倾斜 可以采用mapjoin 原理就是将join操作提前到map 端来执行

 避免数据倾斜。这样操作有一个弊端 就是 jion 的这个表必须是小表 原理就是将小表加载到内存当中 减少时间

 默认的 mapjoin 是打开的:hive.auto.convert.join.noconditionaltask.size=10MB装载到内存的表必须是通过scan的表(不包括group by等操作),如果join的两个表都满足上面的条件,/*mapjoin*/指定表格不起作用,只会装载小表到内存,否则就会选那个满足条件的scan表。

 

www.htsjk.Com true http://www.htsjk.com/hive/38279.html NewsArticle hive 优化, 一 .S ql 优化: 1.  根据不同的业务场景进行 sql优化 2.  去除查询过程中不需要的 column 3.  W here 条件判断再 tablescan 阶段就进行过滤 4.  利用 partition信息 获取有效的数据信...
相关文章
    暂无相关文章
评论暂时关闭