前面说到Hadoop的工作原理的时候,提到了shuffle
1.MapReduce和Spark中shuffle的区别
MapReduce:简单的理解就是将数据从不同的map通过网络传输拉取到同一一个reduce中进行处理,其中涉及到了大量的数据网络传输耗时以及内存磁盘IO耗时,因而是提高mapreduce关键所在。
Spark:spark会将我们的工作job拆成多组taskset,每一组taskset即stage,所有stage构成一个有向无环图DAG,其中数据从上一个stage拉去到下一个stage的过程就是Shuffle,同mapreduce一样,也要涉及到大量的数据网络传输以及内存磁盘IO。
注:stage划分根据宽依赖的,什么事宽依赖和窄依赖呢,
窄依赖:如果父rdd的每一个分区最多被一个子rdd分区使用,那么就是窄依赖,是不会有分stage。
宽依赖:如果子rdd的每一个分区都要依赖父rdd的所有分区,那么就要分stage,也就是要shuffle。
这个章节中,我主要将网上看到的大神们的总结进行小小地归纳,便于我自己的理解。
2.Spark2.X的shulffle小结
在spark1.2以前的版本,spark的shuffle采用的是HashShuffleManager,以后采用的是SortShuffleManager,这里我们就只讲述现在的SortShuffleManager 的大致原理。
SortShuffleManager分成普通机制和bypass运行机制,他们是由spark.shuffle.sort.bypassMergeThreshold这个参数定的,如果read task小于默认值200,那么就是bypass运行机制。
2.1.普通机制
对于每一个task任务
(1)将数据写入内存数据结构中,根据shuffle算子,可能是array或者map结构。
(2)当占用的内存达到一定的阈值的时候,那么对内存中的数据按照key进行排序。
(3)排好序后,分批将数据溢写到磁盘中,默认的batch为10000,本次所有批次溢写后,形成一个磁盘临时文件。
(4)数据写入数据结构中,出现多次溢写操作,会出现多个磁盘临时文件,最后将多个磁盘文件进行merge,一个task一个磁盘文件。
(5)由于一个task任务下游可能由多个task需要写入,因此还会建立一个索引文件,表明下游的某一个task对应的在磁盘文件的位置。
2.2.bypass机制
(1)task为下游的每一个task创建一个临时磁盘。
(2)将数据写入内存中,同时根据下游的task数量,对内存中的数据的key进行hash。
(3)当内存占用达到一定的阈值后,将数据写入对应的临时磁盘中。
(4)最后将多个磁盘合并成一个,并且生成索引文件。
bypass与普通最大的不同,就是不用排序,节省该方面的性能开销,因而更加快速,但是该方法也有问题,因为需要并行打开多个临时磁盘文件,对内存的消耗也比较大。对于spark.shuffle.sort.bypassMergeThreshold小于默认值和不需要排序的操作,可以使用该运行机制。
参考博客:
https://www.cnblogs.com/hd-zg/p/6089230.html
http://www.cnblogs.com/one--way/p/5838460.html