小白最近很长一段时间,都遇到了大数据量,JOB运行慢的问题,看一些优化方法的时候经常提起spark的SQL语句执行过程,对于没有认真研究过SPARK的运行过程的小白来说,看的一知半解,为了打破这个情况,小白认真学习了一下底层,终于清晰了一些,下面小白就总结一下(话术教小白,没有那么的专业,见谅哦)

        一般情况下,我们只是自己写了一段SQL,放在服务器上,他就自动运行了,这样我们就不太了解,他的底层是如何操作的,小白以一个JOIN操作为例,来肢解一下,我们一个JOIN连接的执行过程。

        假如我们有两张表,表m1和m2,里面有数据如下图所示,这两个表以EID进行JOIN操作。

(1)第一步:MAP过程

         将两个表中的EID列作为key,把所有记录加一个标识,标记该记录来自于哪张表,MAP可能有很多个,这里只是简单举例,假如有两个MAP,分布如下图。

(2)第二步:shuffle过程

          进行排序操作。把相同的Key放到在一起。

(3)第三步:Reduce过程

          将符合的都合并到一个里面,如下图展示,其实这是一个笛卡尔积的过程,现在key为a的只有两条纪录,假如有很多条的话,那么a的这个List将会很长。

(4)第四步:输出

         这一步实际就是实现JOIN的操作,将满足条件的数据输出,可以看到该表满足的只有a和b两个纪录,那么输出如下图所示。

spark sql group by数据倾斜 spark的数据倾斜_数据倾斜

       上面描述的,就是我们在进行两个表JOIN的一个处理过程。这里就会涉及到数据倾斜的问题,那么什么是数据倾斜呢?下面小白举两个案例。

数据倾斜的本质就是key分布不均匀,导致分发到不同的reduce上,个别reduce任务特别重,导致其他reduce都完成,而这些个别的reduce迟迟不完成的情况。 发生数据倾斜的原因有

(1)在你的语句中用到group by,sum,distinct等的过程中,就有可能导致数据倾斜,为什么呢?来一个案例

假如对于m1表,该表有1亿的数据,关于a的记录就有9.5千万,b和c的记录分别有250万,那么现在对m1这张表,执行下面SQL

select eid,
       sum(m1) as m1
  from m1
 group by eid;

 那么,这个时候,就会出现数据倾斜,因为在reduce的过程中,相同的key一定会到一个reduce中,那么就有可能为如下情况:

假如说,reduce1耗时2min,reduce耗时30s,那么最终时间是以reduce1的时间为准的,因为要处理完所有reduce过程,才会输出。

spark sql group by数据倾斜 spark的数据倾斜_SPARK_02

(2)数据类型不一致

如果我们关联的字段数据类型不一致的话,也会导致数据倾斜,就比如我们同样用两个id相关联,一个表中是string,另一个表中是bigint,默认的hash操作会按照其中一种类型的值进行分配,导致另一种类型的值会全部分发到同一个reduce中,这种比较容易解决,把两种类型换成一致即可。

(3)大表关联小表

对于join,在判断小表不大于1G的情况下,使用map join会达到比较好的效果。

对于JOIN操作,若不进行map join操作,那么就会按照上面的shuffle方式进行运行,而一旦shuffle,就相当于会有很多相同的key的数据在一个shuffle read task中,然后再放入reduce过程中,就会有个别task运行时间较长,影响性能。这时,如果我们的小表的大小很小,就可以用map join操作,这时就不会发生shuffle,也就不会发生数据倾斜了。

map join的过程如下:

如下图所示,此时MAP过程,是将m1表分到不同的MAP处理,加入说有两台机器来处理,那么此时没台机器都存一份m2的数据,然后进行计算,因为m2这张表也比较小,所以每个计算过程不会很长,并且两个机器计算完成后,直接输出,这中间就不再有shuffle和reduce的过程了。这也就是,在你看执行计划时,会出现有map过程没有reduce过程的情况。但是对于小表太大的情况就不太试用这种情况,如果数据量大,那么每个过程的时候依然很长。另外,map join默认小表的大小为25M,实际中此参数允许的最大值可以修改,但是一般最大不能超过1GB(太大的话Map任务所在的节点内存会撑爆,Hive会报错。另外需要注意的是,HDFS显示的文件大小是压缩后的大小,当实际加载到内存的时候,容量会增大很多,很多场景下会膨胀10倍)。

用map join时,设置参数为:Set hive.auto.convert.join = true;为开启map join操作。

spark sql group by数据倾斜 spark的数据倾斜_数据_03

       小白这次就总结到这里啦,其他的部分,待小白再学习后再总结,如果有疑问或者不对的地方,欢迎大家留言交流哦~