文章目录
- 减少数据量
- 并行化执行
- 开启动态分区
- 开启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的默认值是1Bmapred.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