Spark源码走读6——Shuffle

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

Shuffle 介绍


从图中得知,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有两个子类:


Shuffle Write

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


中可以配置。

接下来看下write的具体方法


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

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


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

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


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

 ShuffleWrite有两个子类:


HashShuffleWriter中的写方法:


再来看下SortShuffleWriter的write方法:


ShuffleReader

HashShuffleReader


SortShuffleManager中的读取对象调用了HashShuffleReader


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

Shuffle partition

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


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


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

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

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

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

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

 

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


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


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



posted on 2015-02-01 12:29  Spark_莫然  阅读(239)  评论(0编辑  收藏  举报