数据倾斜调优
定位:Spark Web UI或本地log查运行较慢的task(查看数据量),确定stage,定位代码位置
查看key的数据分布:countByKey()
解决方案
- 过滤少数导致倾斜的key
适用于少数几个数据量特别多的key对作业的执行和计算结果影响不大
- 提高shuffle并行度
- 两阶段聚合(局部聚合+全局聚合)—适用于reduceByKey等聚合类shuffle算子
将原来相同的key添加随机前缀,得到不同key,使原来在同一个task处理的数据分散到多个task上局部聚合(reduceByKey),接着去除随机前缀,最后进行全局聚合(reduceByKey)
- join操作替换为broadcast+map
适用于join类操作,其中一个RDD数据量较小
- 倾斜key并分拆join操作
join操作两个RDD数据量都大,其中一个key分布均匀,另一个少数key倾斜
思路:
对数据倾斜的RDD统计每个key的数量
将倾斜key对应的数据进行拆分,形成单独RDD11,每个key添加n以内随机前缀,不倾斜的部分形成另一个RDD12
另一个RDD2,过滤倾斜key对应的数据形成RDD21,膨胀(每条数据添加0~n前缀),不倾斜部分形成另一个RDD22
RDD11 join RDD21 = RES1, RDD12 join RDD22 = RES2
RES = RES1 union RES2
- 随机前缀+扩容RDD记性join
join操作两个RDD数据量都大,其中一个key分布均匀,另一个大量key倾斜
思路:
倾斜RDD的每条数据添加n以内的随机前缀
另一个正常RDD每条数据扩容成n条
join
shuffle调优
ShuffleManager:SortShuffleManager —> HashShuffleManager
spark.shuffle.file.buffer(32k)—数据先写入buffer缓冲,满,溢出到磁盘—内存充足,可提高该值,减少shuffle write溢出磁盘文件次数,减少磁盘IO
spark.reducer.maxSizeInFlight(48m)—shuffle read task的buffer缓冲大小,决定每次拉取数据大小—内存充足,可提高,减少数据拉取次数,减少网络传输次数,提升性能
spark.shuffle.manager—设置shuffle manager类型
spark.shuffle.sort.bypassMergeThreshold(200)—shuffle read task数量小于阈值,不进行排序操作—若不要进行排序操作,则调大,自动启用bypass机制。减少排序性能开销
spark.shuffle.consolidateFiles(false)—使用HashShuffleManager时有效,true则开启consolidate机制,大幅度合并shuffle write的输出文件