文章目录

  • 减少数据量
  • 并行化执行
  • 开启动态分区
  • 开启JVM重用
  • 防止数据倾斜
  • Group by引起的数据倾斜
  • Join引起的数据倾斜
  • Skew join
  • 重写业务逻辑
  • MapJoin
  • 自动判断
  • 手动设置
  • map阶段优化
  • reduce阶段优化
  • 方法1
  • 方法2
  • 合并小文件


Hive-hive.groupby.skewindata配置相关问题调研

Join引起的数据倾斜

优化主要分两个方向:skew join和重写业务逻辑

Skew join

set hive.optimize.skewjoin=true;set hive.skewjoin.key=100000; 记录超过hive.skewjoin.key(默认100000)阈值的key值先写入hdfs,然后再进行一个map join的job任务,最终和其他key值的结果合并为最终结果。

重写业务逻辑

这个需要结合具体的场景重写,例如:在日志表与用户表关联时候(通过user_id关联),直接关联可能导致user_id为null的发生数据倾斜,此时可以把日志表中user_id为null的单独处理,如下:

SELECT a.xx, b.yy FROM log a JOIN users b 
            ON a.user_id IS NOT NULL 
                AND a.user_id = b.user_id 
UNION ALL 
SELECT a.xx, NULL AS yy FROM log a WHERE a.user_id IS NULL;

MapJoin

自动判断

set.hive.auto.convert.join=true; 默认值是25mb,小表小于25mb自动启动mapjoin

手动设置

select /*+mapjoin(A)*/ f.a,f.b from A t join B f on (f.a=t.a) 其中,A为小表,将A表复制到所有节点

map阶段优化

通过调整max可以起到调整map数的作用,减小max可以增加map数,增大max可以减少map数。
需要提醒的是,直接调整mapred.map.tasks这个参数是没有效果的。
mapred.min.split.size: 指的是数据的最小分割单元大小;min的默认值是1B
mapred.max.split.size: 指的是数据的最大分割单元大小;max的默认值是256MB

reduce阶段优化

reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定:
hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G)
hive.exec.reducers.max(每个任务最大的reduce数,默认为999)
计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1) 调节的办法

方法1

set hive.exec.reducers.bytes.per.reducer=500000000; 调整hive.exec.reducers.bytes.per.reducer参数的值;

方法2

set mapred.reduce.tasks=15; 调整mapred.reduce.tasks参数的值;

合并小文件

设置map输入的小文件合并

set mapred.max.split.size=256000000;  
//一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;
//一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)  
set mapred.min.split.size.per.rack=100000000;
//执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

设置map输出和reduce输出进行合并的相关参数

//设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true
//设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true
//设置合并文件的大小
set hive.merge.size.per.task = 256*1000*1000
//当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。
set hive.merge.smallfiles.avgsize=16000000