什么是Spark Shuffle

 

答案:每个Spark作业启动运行的时候,首先Driver进程会将我们编写的Spark作业代码分拆为多个stage,每个stage执行一部分代码片段,并为每个stage创建一批Task,然后将这些Task分配到各个Executor进程中执行。一个stage的所有Task都执行完毕之后,在各个executor节点上会产生大量的文件,这些文件会通过IO写入磁盘(这些文件存放的时候这个stage计算得到的中间结果),然后Driver就会调度运行下一个stage。下一个stage的Task的输入数据就是上一个stage输出的中间结果。如此循环往复,直到程序执行完毕,最终得到我们想要的结果。Spark是根据shuffle类算子来进行stage的划分。如果我们的代码中执行了某个shuffle类算子(比如groupByKey、countByKey、reduceByKey、join等等)每当遇到这种类型的RDD算子的时候,划分出一个stage界限来。(答案来自 链接:https://www.jianshu.com/p/069c37aad295 )

以reduceByKey为例

•reduceByKey的含义?

–reduceByKey会将上一个RDD中的每一个key对应的所有value聚合成一个value,然后生成一个新的RDD,元素类型是<key,value>对的形式,这样每一个key对应一个聚合起来的value

•问题:每一个key对应的value不一定都是在一个partition中,也不太可能在同一个节点上,因为RDD是分布式的弹性的数据集,他的partition极有可能分布在各个节点上。

 

•如何聚合?

Shuffle Write上一个stage的每个map task就必须保证将自己处理的当前分区中的数据相同的key写入一个分区文件中,可能会写入多个不同的分区文件中

Shuffle Readreduce task就会从上一个stage的所有task所在的机器上寻找属于自己的那些分区文件,这样就可以保证每一个key所对应的value都会汇聚到同一个节点上去处理和聚合

 

图解Hash-Based Shuffle

spark哪些算子会引起shuffle spark的shuffle算子_读文件

HashShuffle

1、普通机制

每一个map task都会产生R(reduce task的个数)个磁盘小文件,M个task会产生 M*R个磁盘小文件

磁盘小文件过多,影响

(1)写磁盘的时候,会产生大量的写文件对象

(2)读文件时会产生大量的读文件对象

 (3)频繁的大量数据的通信

对象过多--》内存不足--》GC--》OOM

shuffle可能面临的问题

•针对上图中Shuffle过程可能会产生的问题?

–小文件过多,耗时低效的IO操作

–OOM,读写文件以及缓存过多

spark哪些算子会引起shuffle spark的shuffle算子_数据_02

2、合并机制

每一个Executor(1 core)会产生R个磁盘小文件,磁盘小文件数=c*R

 c代表core的数量,一个core一般给他分配2-3个task执行

如何优化解决问题?

•优化后的HashShuffleManager

–优化后的HashShuffleManager的原理

spark哪些算子会引起shuffle spark的shuffle算子_数据_03

SortShuffle运行原理

•SortShuffle的运行机制主要分成两种:

–普通运行机制

–bypass运行机制

•SortShuffle两种运行机制的区别?

SortShuffleManager普通运行机制

spark哪些算子会引起shuffle spark的shuffle算子_数据_04

SortShuffleManager  bypass运行机制

 

spark哪些算子会引起shuffle spark的shuffle算子_运行机制_05

bypass运行机制的触发条件如下:

shuffle reduce task数量小于spark.shuffle.sort.bypassMergeThreshold参数的值。

 

map task ,reduce task 流程图

spark哪些算子会引起shuffle spark的shuffle算子_spark哪些算子会引起shuffle_06

spark哪些算子会引起shuffle spark的shuffle算子_运行机制_07

Executor的内存管理

spark哪些算子会引起shuffle spark的shuffle算子_spark哪些算子会引起shuffle_08