hive性能优化,一篇就够了!!!

  Sql转换mr过程

二  基本sql原则

三 map

四 join

五 reduce

 

  Sql转换mr过程

这里借用一下美团技术文章:https://tech.meituan.com/2014/02/12/hive-sql-to-mapreduce.html

二  基本sql原则

1: 尽量早的过滤数据(谓词下推 hive.optimize.ppd 、避免空值),同时列裁剪 hive.optimize.cp
https://blog.csdn.net/ccstargazing/article/details/104461226 ORC 存储文件探究)
2: 尽量原子操作,避免一个 sql 包含复杂的逻辑。(偏好价格层级案例)
3:join 操作,小表放在左边。
4:union all 的部分可以一次读取多次插入,或者设置参数 hive.exec.parallel.thread.number =n hive.exec.parallel=true
5:group by count(distinct) 的使用场景。 Mapreduce 个数, map 处理方式不同,
6: 尽量减少 map join
7:join 之前对关联键进行 group by 检测,避免数据膨胀。
8:group by 有热点值 . hive.groupby.mapaggr.checkinterval 默认值 100000 ,超过就新起 job
 

三 map

    map任务数量调整:

1 mapred.map.tasks (2) 设定 mapper 的期望数,但不一定会生效。
2:default_mapper_num = total_input_size / dfs.block.size
3:split_size = MAX( mapred.min.split.size (1B),MIN( mapred.max.split.size (64MB) dfs.block.size ))
4:split_num = total_input.size / split_size .
Mapper_num =MIN( split_num,MAX ( defult_mapper_num,mapred.map.tasks ))
总结:减少 mapper 数量,调高 mapred.min.split.size
增加 mapper 数量,降低 mapred.min.split.size ,调高 mapred.map.tasks .

    map倾斜:

问题:
一:上游表大小不均匀,小文件多,导致当前的表的 map 端读取数据分布不均匀。
二: map 端做 聚合 时,某些 map 读取到某个值特别多,主要指 count distinct
方案:
一:合并上游小文件;调整参数合并小文件。
二: distribute by rand() 让数据随机分布。 Distribute by 控制在 map 端如何拆分数据给 redce 端。 Hive 会根据 distribute by 后面的列,根据 reduce 的个数进行数据分发,默认采用 hash 算法。
避免 map 数据倾斜的参数
hive.map.aggr = true (shuffle 之前预聚合,默认 true)
hive.groupby.skewindata = true ( 控制生成两个 MR Job ,默认 false)

 

四 join

问题:
1:join 的某路输入比较小(别的输入较大),引起长尾。
2:join 的每路输入都很大,长尾是空值导致的。
3:join 的每路输入都很大,长尾是热点值导致的。
解决方案:
1: 采用 map join set hive.auto.convert.join =true; hive.mapjoin.smalltable.filesize 默认 25m
2: 空值处理成随机值,避免聚集。
3: 热点值和非热点值分别进行处理( map join ),再 union all

或者set hive.skewjoin.key=100000;--set hive.optimize.skewjoin=false;(默认值)

五 reduce

    reduce任务数量调整:

1:hive.exec.reducers.bytes.per.reducer 设定每个 reducer 能够处理的最大数据量,默认 259M
2:hive.exec.reducers.max 设定每个 job 的最大 reducer 的数量,默认 1009
reducer_num =MIN( total_input_size / hive.exec.reducers.bytes.per.reducer , hive.exec.reducers.max )
总结:调大 reducer 数量,调小 hive.exec.reducers.bytes.per.reducer ,调大 hive.exec.reducers.max
注意事项: reducer 数量与输出文件数量相关。 Reducer 数太多,产生大量小文件,对 HDFS 造成压力,
reducer 太少,每个 reducer 要处理很多数据,拖慢运行时间或者造成 OOM
 

reduce倾斜:

  问题:

        1:对同一个表按照不同维度进行count distinct,造成map端数据膨胀,从而使得下游join和reduce

        出现链路上的长尾。

2:map端直接做聚合时出现key值分布不均匀,造成reduce端长尾。

3:动态分区过多时造成小文件过多,从而引起reduce端长尾。

解决方案:

1: 嵌套编写,先 group by count(*) ;也可以采用 sum(case when)
2: 对热点 key 进行单独处理,再 union all 。(使用 map join 的例子)
3: 把不同条件的数据放入到不同的分区,避免通过多次“ Insert Overwrite” 写人表中。
 

补充:

关联 优化器 set  hive.optimize.correlation= true

       https://cwiki.apache.org/confluence/display/Hive/Correlation+Optimizer

       对于多次取一份数据进行不同的计算很有效。

JVM 重用 set mapred.job.reuse.jvm.num.tasks = 5

     例如将这个参数设成5,那么就代表同一个MR job中顺序执行的5task可以重复使用一个JVM减少启动和关闭的开销。但它对不同         MR job中的task无效。

如果在工作中或者学习过程中,遇到sql跑的比较慢,可以联系我,[email protected],大家一起解决。

 

 

你可能感兴趣的:(hive)