概述
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的常用优化方式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复