在Map和Reduce之间的过程就是Shuffle,Shuffle的性能直接影响整个Spark的性能。所以Shuffle至关重要。

Shuffle 介绍



spark shuffe 是否在磁盘中存储_子类


从图中得知,Map输出的结构产生在bucket中。而bucket的数量是map*reduce的个数。这里的每一个bucket都对应一个文件。Map对bucket书是写入数据,而reduce是对bucket是抓取数据也就是读的过程。

在spark1.1.1中shuffle过程的处理交给了ShuffleBlockManager来管理。

 

ShuffleManager

ShuffleManager中有四个方法:

1)registerShuffleShuffle注册

2)getWriter获得写数据的对象

3)getReader获得读取数据的对象

4)unregisterShuffle移除元数据

5)Stop 停止ShuffleManager

ShuffleManager有两个子类:



spark shuffe 是否在磁盘中存储_数据结构与算法_02


Shuffle Write

Shuffle写的过程需要落地磁盘。在参数



spark shuffe 是否在磁盘中存储_大数据_03


中可以配置。

接下来看下write的具体方法



spark shuffe 是否在磁盘中存储_子类_04


如果consolidateShuffleFiles为true写文件,为false在completedMapTasks中添加mapId。

接下来看下recycleFileGroup这个方法。参数ShuffleFileGroup是一组shuffle文件,每一个特定的map都会分配一组ShuffleFileGroup写入文件。代码如下:



spark shuffe 是否在磁盘中存储_数据_05


这里的valunusedFileGroups = new ConcurrentLinkedQueue[ShuffleFileGroup]()是一个链表队列。往队列中添加shuffleFileGroup

 而在shuffleState.comletedMapTasks这个方法则是往bucket中填充,如果consolidateShuffleFiles为FALSE,则不需要管他。源码中也是这样解释completedMapTasks这个队列:

spark shuffe 是否在磁盘中存储_数据结构与算法_06

源码中的ShuffleState是记录shuffle的一个特定状态。

 ShuffleWrite有两个子类:



spark shuffe 是否在磁盘中存储_数据结构与算法_07


HashShuffleWriter中的写方法:



spark shuffe 是否在磁盘中存储_数据_08


再来看下SortShuffleWriter的write方法:



spark shuffe 是否在磁盘中存储_子类_09


ShuffleReader

HashShuffleReader



spark shuffe 是否在磁盘中存储_子类_10


SortShuffleManager中的读取对象调用了HashShuffleReader

spark shuffe 是否在磁盘中存储_数据结构与算法_11

在Spark1.1.1源码中SortShuffleManager压根就没实现。

Shuffle partition

在RDD API中当调用reduceByKey等类似的操作,则会产生Shuffle了。



spark shuffe 是否在磁盘中存储_大数据_12


根据不同的业务场景,reduce的个数一般由程序猿自己设置大小。可通过“spark.default.par allelism”参数设置。



spark shuffe 是否在磁盘中存储_数据结构与算法_13


1、在第一个MapPartitionsRDD这里先做一次map端的聚合操作。

2、ShuffledRDD主要是做从这个抓取数据的工作。

3、第二个MapPartitionsRDD把抓取过来的数据再次进行聚合操作。

4、步骤1和步骤3都会涉及到spill的过程。

在作业提交的时候,DAGSchuduler会把Shuffle的成过程切分成map和reduce两个部分。每个部分的任务聚合成一个stage。

 

Shuffle在map端的时候通过ShuffleMapTask的runTask方法运行Task。



spark shuffe 是否在磁盘中存储_运维_14


ShuffleMapTask结束之后,最后走到DAGScheduler的handleTaskCompletion方法当中源码如下:



spark shuffe 是否在磁盘中存储_大数据_15


Stage结束后,到reduce抓取过程。查看BlockStoreShuffleFetcher源码如下:



spark shuffe 是否在磁盘中存储_大数据_16