目录
方案一 硬编码
方案二 map join
这篇文章给大家介绍两种数据倾斜的代码层解决方案。
方案1:硬编码,将倾斜的值打散。
方案2:map join
背景:多张表在进行关联时,可能有一个key的值非常多,导致某个reduce处理时间过久,此时产生了数据倾斜。
方案1是用拆分空值和总量较多的key值进行优化。
举例:table 2和table 1关联,key为ucid,table 2 的ucid非常随机,且有一两条ucid为-911的数据,总体没有倾斜。
table1的数据中有许多ucid=-911的数据,假如说是1000w条,那么在关联的时候肯定会出现数据倾斜。
先判断这部分key值是否实际有用,如果没有用,直接转换成随机值,将数据打散。
关联条件为:
on if(table1.ucid=-911,rand(),table1.ucid) = table2.ucid
如果-911的数据是有用的,则需要做其它处理。
在table1中将-911的数据进行“分裂”处理:
if(table1.ucid=-911,concat(table1.ucid,'_',pmod(ceil(rand()*1000000),10)),table1.ucid) as table1.ucid
对table2中-911的数据进行“翻倍”处理:
select
ucid
from
table2
--关联值-911扩展10倍
union
select '-911_0' as ucid
union
select '-911_1' as ucid
union
select '-911_2' as ucid
union
select '-911_3' as ucid
union
select '-911_4' as ucid
union
select '-911_5' as ucid
union
select '-911_6' as ucid
union
select '-911_7' as ucid
union
select '-911_8' as ucid
union
select '-911_9' as ucid
然后进行关联
(
select
ucid
from
table1
)a
left join
(
select
ucid
from
table2
--关联值-911扩展10倍
union
select '-911_0' as ucid
union
select '-911_1' as ucid
union
select '-911_2' as ucid
union
select '-911_3' as ucid
union
select '-911_4' as ucid
union
select '-911_5' as ucid
union
select '-911_6' as ucid
union
select '-911_7' as ucid
union
select '-911_8' as ucid
union
select '-911_9' as ucid
)b
on a.ucid=b.ucid
关联之后别忘记在最外层将table1的ucid还原回来喔(如果要使用的话)
这种方案属于硬编码,只能针对特定的情况进行处理。
将table2作为小表进行map join。
设定参数:
set hive.auto.convert.join=true;
set hive.auto.convert.join.noconditionaltask.size = 30000000;(可根据实际情况设定)
如果table2过大,则做列裁剪。
这样及时table1有几千万条-911的数据,也是在map端就能关联完,不会涉及到shuffle到reduce上进行处理。
这种方法比较通用,不用做太多处理,且如果table2需要关联多次,则可以将table2作为临时表处理。