spark数据倾斜
(1)spark中的数据倾斜的现象?
1、数据倾斜的现象
多数task执行速度较快,少数task执行时间非常长,或者等待很长时间后提示你内存不够,执行失败
(2)数据倾斜的原因?
数据问题:
1、key本身分布不均衡(包括大量的key为空)
2、key的设置不合理
spark使用问题:
shuffle时的并行度不够
计算方式错误
(3)数据倾斜的后果?
1、spark中的stage的执行时间受限于最后那个执行完成的task,因此运行缓慢的任务会拖垮整个程序的运行速度(分布式程序运行的速度由最慢的task决定的)
2、过多的数据在同一个task中执行,将会把excutor撑爆
(4)、spark数据倾斜的处理:
发现数据倾斜的时候,不要急于提高excutor的资源,修改参数或是修改程序,首先要检查数据本身,是否存在问题。是否存在异常数据
1、数据问题造成的数据倾斜?
找出异常的key
如果任务长时间按卡在最后一个任务,首先要对key进行抽样分析,判断是那些key造成的,选取key,对数据进行抽样,统计出现的次数,根据出现次数大小排序,取出前几个
比如: df.select(“key”).sample(false,0.1).(k=>(k,1)).reduceBykey(+).map(k=>(k._2,k._1)).sortByKey(false).take(10)
如果发现多数数据分布都较为平均,而个别数据比其他数据大上若干个数量级,则说明数据倾斜
二、经过分析数据倾斜的情况主要分为三种:
1、null(空值)或者是一些无意义的信息之类的,大多数是这个原因引起的
2.无效数据,大量重复的测试数据或者对结果影响不大的有效数据
3、有效数据:业务导致的正常数据分布
解决方法:
第一二种情况:直接对数据进行过滤操作即可
第三种情况:需要对数据进行一些特殊的操作:常见做法:
1、隔离执行,将异常的key过滤出来进行单独处理,最后与正常的数据的处理结果进行union操作
2、对key先添加随机值,进行操作后,去掉随机值,再进行操作。
3、使用reducebykey代替groupbykey用于每个key对应的多个value进行merge操作,最重要的是能够在本地进行merge操作
4、使用mapjoin
案例
如果使用reduceByKey因为数据倾斜造成运行失败的问题。具体操作流程如下:
(1) 将原始的 key 转化为 key + 随机值(例如Random.nextInt)
(2) 对数据进行 reduceByKey(func)
(3) 将 key + 随机值 转成 key
(4) 再对数据进行 reduceByKey(func)
案例操作流程分析:
假设说有倾斜的Key,我们给所有的Key加上一个随机数,然后进行reduceByKey操作;此时同一个Key会有不同的随机数前缀,在进行reduceByKey操作的时候原来的一个非常大的倾斜的Key就分而治之变成若干个更小的Key,不过此时结果和原来不一样,怎么破?进行map操作,目的是把随机数前缀去掉,然后再次进行reduceByKey操作。(当然,如果你很无聊,可以再次做随机数前缀),这样我们就可以把原本倾斜的Key通过分而治之方案分散开来,最后又进行了全局聚合
注意1: 如果此时依旧存在问题,建议筛选出倾斜的数据单独处理。最后将这份数据与正常的数据进行union即可。
注意2: 单独处理异常数据时,可以配合使用Map Join解决。
2、spark使用不当造成的数据倾斜?
(1)提高shuffle并行度
dataFrame和sparkSql可以设置spark.sql.shuffle.partitions参数控制shuffle的并发度,默认为200。
rdd操作可以设置spark.default.parallelism控制并发度,默认参数由不同的Cluster Manager控制。
局限性: 只是让每个task执行更少的不同的key。无法解决个别key特别大的情况造成的倾斜,如果某些key的大小非常大,即使一个task单独执行它,也会受到数据倾斜的困扰。
(2)避免不必要的shuffle如使用小表广播然后合并join后的结果
(3)使用map join代替reduce join 在小表不是特别大可以避免shuffle的过程
对于Spark中的数据倾斜问题你有什么好的方案?
1)前提是定位数据倾斜,是OOM了,还是任务执行缓慢,看日志,看WebUI
2)解决方法,有多个方面
· 避免不必要的shuffle,如使用广播小表的方式,将reduce-side-join提升为map-side-join
·分拆发生数据倾斜的记录,分成几个部分进行,然后合并join后的结果
·改变并行度,可能并行度太少了,导致个别task数据压力大
·两阶段聚合,先局部聚合,再全局聚合
·自定义paritioner,分散key的分布,使其更加均匀