我是靠谱客的博主 苹果樱桃,最近开发中收集的这篇文章主要介绍HIVE的常用优化方式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量

开启hive中间传输数据压缩功能

set hive.exec.compress.intermediate=true;

开启mapreduce中map输出压缩功能

set mapreduce.map.output.compress=true;

设置mapreduce中map输出数据的压缩方式

set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;

 

2.开启Reduce输出阶段压缩

开启hive最终输出数据压缩功能

set hive.exec.compress.output=true;

开启mapreduce最终输出数据压缩

set mapreduce.output.fileoutputformat.compress=true;

设置mapreduce最终数据输出压缩方式

set mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodec;

设置mapreduce最终数据输出压缩为块压缩

set mapreduce.output.fileoutputformat.compress.type=BLOCK;

 

在实际的项目开发当中,hive表的数据存储格式一般选择:orc或parquet。压缩方式一般选择snappy。

和Parquet类似,ORC文件也是以二进制方式存储的,所以是不可以直接读取,ORC文件也是自解析的,它包含许多的元数据,这些元数据都是同构ProtoBuffer进行序列化的

 

来自 <https://www.cnblogs.com/ITtangtang/p/7677912.html>

 

3.Fetch抓取(Hive可以避免进行MapReduce

在hive-default.xml.template文件中hive.fetch.task.conversion默认是more,该属性修改为more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

 

4.本地模式

Hive的输入数据量非常小时,为查询触发执行任务时消耗可能会比实际job的执行时间要多的多,Hive可以通过本地模式在单台机器上处理所有的任务,执行时间可以明显被缩短。

设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化

set hive.exec.mode.local.auto=true;  --开启本地mr

--设置local mr的最大输入数据量,当输入数据量小于这个值时采用local  mr的方式,默认为134217728,即128M

set hive.exec.mode.local.auto.inputbytes.max=51234560;

--设置local mr的最大输入文件个数,当输入文件个数小于这个值时采用local mr的方式,默认为4

set hive.exec.mode.local.auto.input.files.max=10;

 

5.Join的优化

5.1.Map端Join(小表join大表)

如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜

可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。

map端join的参数设置

set hive.auto.convert.join = true; -- 默认为true

大表小表的阈值设置:

set hive.mapjoin.smalltable.filesize= 25000000;

小表的输入文件大小的阈值(以字节为单位);如果文件大小小于此阈值,它将尝试将common join转换为map join。

在实际使用中,只要根据业务把握住小表的阈值标准即可,hive会自动帮我们完成mapjoin,提高执行的效率。

 

5.2.大表Join大表

2.1空KEY过滤

有时join超时是因为某些key对应的数据太多,而相同key对应的数据都会发送到相同的reducer上,从而导致内存不够

很多情况下,这些key对应的数据是异常数据,我们需要在SQL语句中进行过滤。例如key对应的字段为空:

不过滤

INSERT OVERWRITE TABLE jointable

SELECT a.* FROM nullidtable a JOIN ori b ON a.id = b.id;

结果:

No rows affected (152.135 seconds)

过滤

INSERT OVERWRITE TABLE jointable

SELECT a.* FROM (SELECT * FROM nullidtable WHERE id IS NOT NULL ) a JOIN ori b ON a.id = b.id;

结果:

No rows affected (141.585 seconds)

 

2.2空key转换

有时虽然某个key为空对应的数据很多,但是相应的数据不是异常数据,必须要包含在join的结果中,此时我们可以表a中key为空的字段赋一个随机的值,使得数据随机均匀地分不到不同的reducer上,例如:

不随机分布:

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

set mapreduce.job.reduces=7;

INSERT OVERWRITE TABLE jointable

SELECT a.*

FROM nullidtable a

LEFT JOIN ori b ON CASE WHEN a.id IS NULL THEN 'hive' ELSE a.id END = b.id;

 

No rows affected (41.668 seconds)   52.477

结果:这样的后果就是所有为null值的id全部都变成了相同的字符串,及其容易造成数据的倾斜(所有的key相同,相同key的数据会到同一个reduce当中去)

 

为了解决这种情况,我们可以通过hive的rand函数,随记的给每一个为空的id赋上一个随机值,这样就不会造成数据倾斜

随机分布:

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

set mapreduce.job.reduces=7;

INSERT OVERWRITE TABLE jointable

SELECT a.*

FROM nullidtable a

LEFT JOIN ori b ON CASE WHEN a.id IS NULL THEN concat('hive', rand()) ELSE a.id END = b.id;

 

 

No rows affected (42.594 seconds)

大表join小表或者小表join大表,就算是关闭map端join的情况下,在新的版本当中基本上没有区别了(hive为了解决数据倾斜的问题,会自动进行过滤)

最后

以上就是苹果樱桃为你收集整理的HIVE的常用优化方式的全部内容,希望文章能够帮你解决HIVE的常用优化方式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部