从整体功能上看,两者并没有大的差别。 都是将 mapper(Spark 里是 ShuffleMapTask)的输出进行 partition,不同的 partition 送到不同的 reducer(Spark 里 reducer 可能是下一个 stage 里的 ShuffleMapTask,也可能是 ResultTask)。Reducer 以内存作缓冲区,边 shuffle 边 aggregate 数据,等到数据 aggregate 好以后进行 reduce(Spark 里可能是后续的一系列操作)。 从流程的上看,两者差别不小。 Hadoop MapReduce 是 sort-based,进入 combine和 reduce的 records 必须先 sort。这样的好处在于 combine/reduce可以处理大规模的数据,因为其输入数据可以通过外排得到(mapper 对每段数据先做排序,reducer 的 shuffle 对排好序的每段数据做归并)。以前 Spark 默认选择的是 hash-based,通常使用 HashMap 来对 shuffle 来的数据进行合并,不会对数据进行提前排序。如果用户需要经过排序的数据,那么需要自己调用类似 sortByKey的操作。在Spark 1.2之后,sort-based变为默认的Shuffle实现。 从流程实现角度来看,两者也有不少差别。 Hadoop MapReduce 将处理流程划分出明显的几个阶段:map, spill, merge, shuffle, sort, reduce等。每个阶段各司其职,可以按照过程式的编程思想来逐一实现每个阶段的功能。在 Spark 中,没有这样功能明确的阶段,只有不同的 stage 和一系列的 transformation,所以 spill, merge, aggregate 等操作需要蕴含在 transformation中。
Hadoop 2.7.x Shuffle过程是sort-based过程,在shuffle过程中会发生排序行为; Spark 2.2.x Spark ShuffleManager 分为HashShuffleManager和SortShuffleManager。Spark 1.2后 默认为SortShuffleManager,在普通模式下,shuffle过程中会发生排序行为;Spark可以根据业务场景需要进行ShuffleManager选择--Hash Shuffle Manager / Sort ShuffleManager(普通模式和bypass模式)。
Hadoop Shuffle过程总共会发生3次排序行为,详细分别如下: 第一次排序行为:在map阶段,由环形缓冲区溢出到磁盘上时,落地磁盘的文件会按照key进行分区和排序,属于分区内有序,排序算法为快速排序; 第二次排序行为:在map阶段,对溢出的文件进行combiner合并过程中,需要对溢出的小文件进行归并排序、合并,排序算法为归并排序; 第三次排序行为:在reduce阶段,reducetask将不同maptask端文件拉去到同一个reduce分区后,对文件进行合并,归并排序,排序算法为归并排序;
Spark Shuffle过程在满足Shuffle Manager为SortShuffleManager,且运行模式为普通模式的情况下才会发生排序行为,排序行为发生在数据结构中保存数据内存达到阈值,在溢出磁盘文件之前会对内存数据结构中数据进行排序; Spark中Sorted-Based Shuffle在Mapper端是进行排序的,包括partition的排序和每个partition内部元素进行排序。但是在Reducer端没有进行排序,所以job的结果默认情况下不是排序的。 Sorted-Based Shuffle 采用Tim-Sort排序算法,好处是可以极为高效的使用Mapper端的排序成果完成全局排序。
hadoop:map端保存分片数据,通过网络收集到reduce端。
spark:spark的shuffle是在DAGSchedular划分Stage的时候产生的,TaskSchedule要分发Stage到各个worker的executor。
减少shuffle可以提高性能。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。