hive优化方法

Posted

tags:

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

参考技术A 1、列裁剪和分区裁剪

2、谓词下推

3、sort by 替换order by 

4、group by 代替distinct

5、group by 配置调整

map 端预聚合:set hive.map.aggr=true ; set hive.groupby.mapaggr.checkinterval=100000

倾斜均衡配置项:set hive.groupby.skewindate=true

6、join优化

6.1 大小表,小表前置

6.2 多表Join时key相同

6.3 利用mapjoin特性

6.4 分桶表 mapjoin

6.5 倾斜均衡配置项:

设置hive.optimize.skewjoin=true,开启后,在join过程中hive会将计数超过阈值hive.skewjoin.key(默认100000)的倾斜key对应的行临时写进文件中,然后再启动另一个job做map join生成结果。通过hive.skewjoin.mapjoin.map.task参数还可以控制第二个job的mapper数量,默认10000.

6.7 优化sql处理join数据倾斜

6.7.1、空值或无意义的值:若不需要空值数据,就提前写到where语句过滤掉,如果需要保留的话,将空值key用随机方式打散。

6.7.2、单独处理倾斜key

6.7.3、不同数据类型,join的关联字段类型不一样,导致耗时长,所以需要注意做类型转换(join关联字段,一个是int,一个是string,,计算key的hash值时默认时int类型做的,这样导致所有真正的string类型的key都分配到一个reducer上了)

6.7.4、mapjoin的小表比较大的时候,,无法直接使用mapjoin,则 select/*+mapjoin(b)*/  from  a left join ( select /*+mapjoin (b)*/ from b inner join a )

6.8、mapreduce 优化

6.8.1、调整mapper数

mapper数量与输入文件的split数息息相关。如果想减少mapper数,就适当提高mapred.min.split.size,split数就减少了;如果想增大mapper数,除了降低maperd.min.split.size之外,也可以提高mapred.map.task;一般来讲,如果输入文件是少量大文件,就减少mapper数;如果是大量非小文件,就增大mapper数,如果是小文件,就喝吧小文件

6.8.2 调整reducer数

使用参数mapred.reduce.task可以直接设定reducer数量,如果不设置的话,hive会自行推测,推测逻辑如下:

参数hive.exec.reducers.bytes.per.reducer.设定每个reducer能够处理的最大的数据量,默认时1G

参数hive.exec.reducers.max设定每个job的最大的reducer数量,默认时999或者1009

得到reducer数:reducers_num=min(total_input_size/reducers.bytes.per.reducer,reducers.max)

reducer数量与输出文件的数量相关,如果reducer数太多,会产生大量小文件,对hdfs造成压力,如果reducer数太少,每个reducer要处理很多数据,容易拖慢运行时间或造成oom

6.8.3 合并小文件

输入阶段合并:需要更改hive的输入文件格式,即参数hive.input.format,默认值是org.apache.hadoop.hive.ql.io.hiveiputformat,我们该成org.apache.hadoop.hive.ql.io.combinehiveinputformat.

这样比调整mapper数时,又多出两个参数,分别是mapred.min.split.size.per.node和mapred.min.split.size.per.rack,含义是单节点和单机架上的最小split大小。如果发现又split大小小于这两个默认值100MB,则会进行合并

输出阶段合并:直接将hive.merge.mapfiles和hive.merge.mapredfiles都设置为true即可。

hive.merge.mapfiles表示将map-only任务的输出合并

hive.merge.mapredfiles表示将map-reduce任务的输出合并

另外hive.merge.size.per.task可以指定每个task输出后合并文件大小的期望值

hive.merge.size.smallfiles.avgsize可以指定所有输出文件大小的均值阈值,默认时1G

6.9 启用压缩

压缩job的中间结果数据和输出数据,可以少量CPU时间节省出很多空间。压缩方式一般选择snappy,效率最高,要启用中间压缩,需要设定:

hive.exec.compress.intermediate为true,同时指定压缩方式hive.intermediate.compression.code为org.apache.hadoop.io.compress.snappycode.

另外,参数hive.intermediate.compression.type可以选对块block还是对记录record压缩,block压缩率比较高,输出压缩的配置基本相同:打开hive.exec.compress.output

6.10 jvm重用

在mr job中,默认时每执行一个task就会启动一个jvm,如果task非常小而且碎,那么jvm启动和关闭耗时都会比较长。可以通过调节参数mapred.job.reuse.jvm.num.task来重用。例如将这个参数设置为5,那么久代表同一个mr job中顺序执行的5各task可以重复使用一个jvm,减少启动和关闭开销,但是他对不同mr job的task无效

6.11 采用合适的存储格式

6.12 数据倾斜

数据倾斜原因:1、join 倾斜 2、聚合倾斜

group by 倾斜: group by 字段中某个字段的值过多,导致处理这个值得reduce耗时很久

解决方法:set hive.map.aggr=true;  -- 表示开启map端聚合

set hive.groupby.skewindata=true;  注意:只能对单个字段聚合 , 生成两个map job ,第一个map job中map输出结果随机分布到reduce中,每个reduce做部分聚合操作,并输出结果,这样相同的groub key有可能被分发到不同的reduce中,从而达到负载均衡的目的;第二个map job再根据预处理的数据结果按照group by key分布到reduce中,这个过程可以保证相同的key被分到同一个reduce中,最后完成最终的聚合操作

6.13 优化in、exists语句

使用left semi join 替换in 、exists

6.14 合并 mapreduce操作

multi-group by 是hive的一个非常好的特性,它使得hive中利用中间结果变更非常方便

例如:

from ( select a.status,b.school from status_update a join profilees b on (a.userid=b.suerid)) subq1

insert overwirte table a1 partition(ds='2021-03-07') 

select subq1.school,count(1) group by subq1.school

insert overwrite table b1 partition(ds='2021-03-07')

select subq1.status,count(1) group by subq1.status

上述语句使用了multi-group by特性联系group by 2次数据,使用不同的group by key,这一特性可以减少一次mapreduce操作

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

Hive与优化方法

Hive与优化方法

Hive优化的十大方法

Hive优化

Hive高级优化

Hive优化