sparks 中数据倾斜的大坑

这两天弄训练数据的时候碰到了一个大坑
本来数据集就比较大,在划训练样本的时候,训练样本的分布就出现了不均匀的情况(有的parition多,有的少),主要的症状体现在200个parition的dataframe,前面190个task都run的飞快,剩下10个task,处理的一个比一个慢。点开每个task的input data size,就会发现很多parition都是空的,或者只有几KB,在run的task中,input data一个大过一个。
这是典型的数据倾斜现象,不及时处理简直后患无穷。
常规的做法,对dataframe进行“撒盐”处理:就是append上一列column,赋值为随机数,然后按照这个随机数做聚合操作,能大大降低数据倾斜的发生。
第二是由于数据量本来就多,解决了数据倾斜的问题后,在后续的处理当中,频繁出现了分布式集群中worker节点失联的情况。一般这样是由于每个节点的worker计算量太大,导致超时了,或者是因为节点OOM了,导致节点挂掉了。
这个可以看下spark UI,看看机器的metric都有没啥问题。如果是计算量太大导致的超时,并不建议修改spark的timeout和heartbeat时间,理论上应该是有更elegant的方法可以避免超时的问题。
我后续的操作应该就是每个worker的计算量太大了,因为function要操作的数据量都比较大,这样很容易造成超时,也很容易导致,即使做了shuffle,已然数据分配不均。所以这次的教训就是,尽量让dataframe的function(udf)每次操作的数据量少,这样才能最大程度利用分布式。还有就是如果数据量大,操作复杂的话,要及时触发action操作,不然到后面计算图就特别大了,算起来老慢了。

所以作此总结:

  1. 及时触发action,避免后面某次一次性触发前面厚重的计算图
  2. 根据机器,及时提高计算并行度(通过设置spark的参数,或者通过repartition增加df parition的数量,和core总数相同)
  3. 手动shuffle(撒盐
  4. udf应该尽可能处理少量的数据,和简单的逻辑

你可能感兴趣的:(sparks 中数据倾斜的大坑)