hive 调优过程

2019-01-18  本文已影响0人  Hunter严

Hive 统计优化

在数据量非常大的时候,distinct会将所有的统计信息加载到一个reducer里取执行,这就是所谓的数据倾斜。而group by会把相同key的记录放到一个reducer区计算,因此效率会提高很多。

不用数据类型造成的倾斜

空值或者大量重复着造成的倾斜,给于rand()

列裁剪

分区裁剪

Mapper join

有子查询的选择过滤掉不需要的列,提升效率

复杂逻辑python实现的优化

简单快速

Join优化特例

相同的join key 只需要一个task,大大提升了时间

Left semi join 优化   sql exists替代

返利166多T

Apache 33T

Varnish 17T

hive 调优过程

语法层面

参数层面

1 逻辑代码调整

(1)规范sql

(2)查看执行计划,分析表数据, 减少jobs数,设置合理的map reduce的task数,能有效提升性能

(3)解决数据倾斜问题

通用算法set hive.groupby.skewindata=true,

数据量较大的情况下,慎用count(distinct),count(distinct)容易产生倾斜问题

如统计淘宝一天uv,30亿的pv ,按照性别统计分配2个reduce,每个reduce处理15亿数据 ,那么可以根据性别和userid 分组排序统计

数据倾斜是导致效率大幅降低的主要原因,可以采用多一次 Map/Reduce 的方法, 避免倾斜

避实就虚,用 job 数的增加,输入量的增加,占用更多存储空间,充分利用空闲 CPU 等各种方法,分解数据倾斜造成的负担

空值填充,数据转换造成的倾斜解决

--问题

[if !supportLists]·        [endif]数据量大不是问题,数据倾斜是个问题。

[if !supportLists]·        [endif]jobs数比较多的作业运行效率相对比较低,比如即使有几百行的表,如果多次关联多次汇总,产生十几个jobs,耗时很长。原因是map reduce作业初始化的时间是比较长的。

[if !supportLists]·        [endif]sum,count,max,min等UDAF,不怕数据倾斜问题,hadoop在map端的汇总合并优化,使数据倾斜不成问题。

[if !supportLists]·        [endif]count(distinct ),在数据量大的情况下,效率较低,如果是多count(distinct )效率更低,因为count(distinct)是按group by 字段分组,按distinct字段排序,一般这种分布方式是很倾斜的。举个例子:比如男uv,女uv,像淘宝一天30亿的pv,如果按性别分组,分配2个reduce,每个reduce处理15亿数据。

  面对这些问题,我们能有哪些有效的优化手段呢?下面列出一些在工作有效可行的优化手段:

[if !supportLists]·        [endif]良好的sql 书写习惯,如数据类型转换问题

[if !supportLists]·        [endif]解决数据倾斜问题。

[if !supportLists]·        [endif]减少job数。

[if !supportLists]·        [endif]设置合理的map reduce的task数,能有效提升性能。(比如,10w+级别的计算,用160个reduce,那是相当的浪费,1个足够)。

[if !supportLists]·        [endif]了解数据分布,自己动手解决数据倾斜问题是个不错的选择。set hive.groupby.skewindata=true;这是通用的算法优化,但算法优化有时不能适应特定业务背景,开发人员了解业务,了解数据,可以通过业务逻辑精确有效的解决数据倾斜问题。

[if !supportLists]·        [endif]数据量较大的情况下,慎用count(distinct),count(distinct)容易产生倾斜问题。

[if !supportLists]·        [endif]对小文件进行合并,是行至有效的提高调度效率的方法,假如所有的作业设置合理的文件数,对云梯的整体调度效率也会产生积极的正向影响。

[if !supportLists]·        [endif]优化时把握整体,单个作业最优不如整体最优。

配置角度优化

列裁剪

Hive 在读数据的时候,可以只读取查询中所需要用到的列,而忽略其它列,节省了读取开销,中间表存储开销和数据整合开销。

裁剪所对应的参数项为:hive.optimize.cp=true(默认值为真)

分区裁剪

分区参数为:hive.optimize.pruner=true(默认值为真)

Join

多个join 条件相同的可以形成只查询之后再jion 减少jobs数 提高执行效率

Mapjoin

set hive.auto.convert.join=true;

sethive.mapjoin.smalltable.filesize=3000000;

sethive.auto.convert.join.noconditionaltask=true;

sethive.auto.convert.join.noconditionaltask.size=3000000;

hive.join.emit.interval= 1000

hive.mapjoin.size.key =10000

hive.mapjoin.cache.numrows= 10000

group by 操作

Map端部分聚合

hive.map.aggr=true(用于设定是否在 map 端进行聚合,默认值为真) hive.groupby.mapaggr.checkinterval=100000(用于设定 map 端进行聚合操作的条目数)

有数据倾斜时进行负载均衡

hive.groupby.skewindata,当选项设定为 true 是,生成的查询计划有两 个 MapReduce 任务。在第一个MapReduce 中,map 的输出结果集合会随机分布到 reduce中, 每个 reduce 做部分聚合操作,并输出结果。这样处理的结果是,相同的 Group By Key 有可 能分发到不同的 reduce 中,从而达到负载均衡的目的;第二个MapReduce 任务再根据预处 理的数据结果按照 Group By Key 分布到 reduce中(这个过程可以保证相同的 Group By Key 分布到同一个 reduce中)

合并小文件

我们知道文件数目小,容易在文件存储端造成瓶颈,给 HDFS 带来压力,影响处理效率。对此,可以通过合并Map和Reduce的结果文件来消除这样的影响。

  用于设置合并属性的参数有:

是否合并Map输出文件:hive.merge.mapfiles=true(默认值为真)

是否合并Reduce 端输出文件:hive.merge.mapredfiles=false(默认值为假)

合并文件的大小:hive.merge.size.per.task=256*1000*1000(默认值为 256000000)

程序角度优化

熟练sql,写出高效率的查询

空值赋予随机值

不同数据类型关联转为同一数据类型

巧用临时表

Union all 并行设置

优化常用手段

[if !supportLists]·        [endif]hive.exec.reducers.bytes.per.reducer

  #这个参数控制一个job会有多少个reducer来处理,依据的是输入文件的总大小。默认1GB。

[if !supportLists]·        [endif]hive.exec.reducers.max    #这个参数控制最大的reducer的数量, 如果 input / bytes per reduce > max  则会启动这个参数所指定的reduce个数。  这个并不会影响mapre.reduce.tasks参数的设置。默认的max是999。

[if !supportLists]·        [endif]mapred.reduce.tasks #这个参数如果指定了,hive就不会用它的estimation函数来自动计算reduce的个数,而是用这个参数来启动reducer。默认是-1

参数设置

如果reduce太少:如果数据量很大,会导致这个reduce异常的慢,从而导致这个任务不能结束,也有可能会OOM 2、如果reduce太多:  产生的小文件太多,合并起来代价太高,namenode的内存占用也会增大。如果我们不指定mapred.reduce.tasks, hive会自动计算需要多少个reducer。

上一篇下一篇

猜你喜欢

热点阅读