hive优化
-
数据倾斜
数据倾斜是指在进行数据计算的时候,因为数据的分散度不够,导致大量数据集中到一台或几台服务器上计算,而这些数据的计算速度远远低于数据计算的平均速度,进而导致整个数据计算速度变慢。 -
开发基本原则
尽量少用select * ,这样会将所有字段数据都查出来,而你用的时候可能根本就用不到所有字段,造成了额外的I/O开销;另外,使用这种方式数据库需要先Query Table Metadata For Columns(询问数据库表结构列名),一定程度上为数据库增加了负担(影响网络传输的性能),但是实际上,两者效率差别不大。
尽量原子化操作,尽量避免一个SQL包含复杂逻辑,可以使用中间表来完成复杂的逻辑。
大表和小表的join操作使用map join的方式。
尽量尽早地过滤数据,减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段。
eg:
select ...
from A
join B
on A.userid = B.userid
where
A.userid>100
and B.userid<100
and A.dt='20210420'
and B.dt='20210420';
将如上代码改为如下写法
select ....
from
(select ....
from A
where dt='20210420'
and userid>100
) a
join
(select ....
from B
where dt='20210420'
and userid < 100
) b
on a.userid = b.userid;
-
数据倾斜
-
日常使用的时候,经常会出现数据倾斜的可以归纳为如下几点:
-
group by
-
join
-
distinct
-
count(distinct xxx)
-
数据倾斜优化方案
对于group by产生的数据倾斜,解决方案如下:
set hive.map.aggr=true;
在map段做局部聚合,效率更高但是需要更多的内存。
set hive.groupby.skewindata = true;
查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
set hive.groupby.mapaggr.checkinterval =100;
在 Map 端进行聚合操作的条目数目,具体值根据自己的数据量设置。
对于join产生的数据倾斜,解决方案如下:
set hive.auto.convert.join=true;
当一个大表和一个小表join的时候,将小表放到内存中去,然后再对大表做map操作。
set hive.optimize.skewjoin=true;
如果是join 过程出现倾斜 应该设置为true。
set hive.skewjoin.key=1000; (具体值根据自己的数据量设置)
这个参数是join的键对应的记录条数超过这个值则会进行分拆,值根据具体数据量设置。
对于distinct产生的数据倾斜,解决方案如下:
使用group by的方式重写hsql,完成去重操作,然后对group by操作设置处理数据倾斜参数。
distinct 写法案例以及group by改写优化写法如下:
eg:
--distinct 写法
select distinct id,name from tb;
--group by 改写优化如下
set hive.groupby.skewindata = true;
set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval =100;
select id,name from tb group by id,name;
对于count(distinct xxx)产生的数据倾斜问题解决方案如下:
--count(distinct)
select count(distinct id) as id_num from tb;
--优化
set hive.groupby.skewindata = true;
set hive.map.aggr=true;
set hive.groupby.mapaggr.checkinterval =100;
select count(id) as id_num from (select id from tb group by id);
数据的倾斜还包括,大量的join连接key为空的产生数据倾斜,空的key都hash到一个reduce上去了。
解决这个问题的方式就是把空的key和非空的key做区分, 空的key不做join操作,单独取出放到临时表中,其它数据join完成后在和这部分数据做union all操作。