数据倾斜的话题虽然已经老生常谈,但spark3的出现又让这一问题有了新的处理方式,这里就根据个人使用情况总结一波。
首先数据倾斜是分布式计算过程中的一个现象,具体表现常为“整个程序执行非常慢,查看日志或UI界面可以发现程序一直在计算某个task,出现卡住的情况”,出现这种情况就是数据倾斜了。
数据倾斜出现的原因:在shuffle阶段有的reduce处理了很多的数据量,有的reduce处理的较少,就导致了数据倾斜的出现。
数据是一个比较容易出现且比较烦人的问题,解决思想主要为使用各种方式让shuffle中各个reduce处理的数据量差不多,这样计算效率就会大大提升。
在早期都是通过改变代码来处理或缓解数据倾斜的。
eg:
select
A.*,B.*
from A left join B on A.id=B.id
上述是一个很简单的join案例,如果A表和B(暂不考虑broadcast join)的id各个值的count都比较均匀的话这个join自然没有大问题。当A表的id出现某几个值特别多的时候在join时就会出现数据倾斜,这种解决方案一般会对A表的存在数据倾斜的id值加随机值,并对B表进行扩容。
上面的理论很多人都知道,但真正去实现的时候却慌了神,下面给大家演示怎么做:
B表是需要扩容的,扩容主要用的是列转行的知识,下面的扩容的方法
eg:
select
concat(index,"_",id) as id, other_column,......
from (
select
id,other_column,......
from B
where id in(...)
) t lateral view posexplode(split(space(100),"")) tmp_table as index,value
那么完整的写法可以这样写:
eg:
select
A.*,B.*
from A left join B
where id not in (....倾斜id)
union all
select
A.*,B.*
from (select
concat(cast(rand()*100 as int),"_",id) as id,other_column,......
from A
where id in(...倾斜id)
) new_A left join (
select
concat(index,"_",id) as id, other_column,......
from (
select
id,other_column,......
from B
where id in(...倾斜id)
) t lateral view posexplode(split(space(100),"")) tmp_table as index,value
)new_B
on new_A.id=new_B.id
我这里只是随手写了一段sql,仅供参考,需要根据实际场景去改造来提升效率
(持续更新中。。。)