hive的优化:
(1)使用mapjoin
①mapjoin的原理是把小表加载到内存中在map端进行join,避免reduce处理
②多大的表被视为小表呢?默认是25M以下是小表,通过配置参数set hive.mapjoin.smalltable.filesize=25000000
③如何开启mapjoin呢?set hive.auto.convert.join=true
(2)Fetch抓取(默认就是more)
①什么是fetch?Hive中对某些情况的查询可以不走mapreduce
②fetch的级别有哪些?more(默认)、minimal(老版本)、none
more表示在全局查找和字段查找、limit等都不会走mapreduce
(3)合理设置map个数
①为什么合理设置map个数能够优化hive?
map个数等于切片的数量
map也不是越多越好,如果一个文件有多个小文件组成,那么每个小文件都被当作一个块,用一个map来完成,那么map任务的启动时间和初始化时间远远大于逻辑处理时间,那么就会造成资源的浪费。
map的个数也并不是128M就是最好的,比如一个127M的文件块中只有一个或两个字段,却有几千万条记录,并且map处理逻辑比较复杂,用一个map去执行,也是会很耗时间的
②map个数怎么合理设置呢?
对于小文件场景,我们需要减少map的个数
对于大文件,但是任务逻辑复杂,map执行非常慢,我们需要增加map的个数
③如何设置减少和增大map的个数呢?
减少map的个数:第一种可以使用CombineHiveInputformat
第二种通过调整切片的大小,set mapred.max.split.size,增大这个参数可以减少map的个数
增大map的个数:通过调整切片的大小,set mapred.max.split.size,减小这个参数可以增大map的个数
(4)合理设置reduce个数
①为什么要合理设置reduce个数能够优化hive?
reduce默认是-1,也就是说1G的文件,默认是有1G/256M=4个reduce
增大reduce个数可以增加reduce过程的并行度
②reduce个数设置多少比较合理呢?
reduce个数就等于输出文件的个数,所以也不能设置非常多
③如何设置reduce个数?
方式1:通过set mapreduce.job.reduces=15;
方式2:每个reduce默认处理的数据量是256M,set hive.exec.reducers.bytes.per.reducer=256000000
每个任务的最大reduce数,默认是1009,set hive.exec.reducers.max=1009
计算reduce的个数为:N=min(1009, 总的输入量/256M)
(5)设置map和reduce并行执行
①默认情况下是map阶段执行完成了,reduce端才会从map拉取对应分区的数据,
而开启map和reduce并行执行,map端处理的部分数据会传给reduce,reduce先聚合部分,最后再聚合所有的
②如何开启map和reduce并行执行呢?
set hive.exec.parallel = true;(默认false)
(6)采用列式存储和压缩
①dwd、dws、dwt层的数据可以使用parquet列式存储,和lzo压缩,原因parquet支持切片
②为什么ods层不采用列式存储?
ods层我们仅仅使用的是lzo压缩,原始数据不做处理,做数据备份的作用
③为什么ads层不采用列式存储?
ads层不能采用parquet列式存储,不需要压缩
(7)解决小文件问题
①hive中怎么产生的小文件呢?
原因1:动态分区插入数据的时候,产生小文件,导致map个数剧增
如何开启动态分区?set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict
原因2:reduce个数太多,reduce个数=输出文件的个数
②如何控制hive中的小文件呢?
方式1:在map执行前聚合小文件,使用CombinerHiveInputFormat
方式2:开启JVM重用,set mapreduce.job.jvm.numtasks=10;
(8)开启map端的Combiner(不影响最终业务逻辑)
set hive.map.aggr=true
(9)行列过滤
①什么是行列过滤?
列处理的时候,只拿需要列,尽量少使用select*
行处理的时候,当两张表join的时候,先条件过滤,然后再关联两个表
Hive优化总结
最新推荐文章于 2024-05-10 14:54:23 发布