简单说一下 hadoop 和 spark 的 shuffle 相同和差异?

1)从 high-level 的角度来看,两者并没有大的差别。 都是将 mapper(Spark 里是 ShuffleMapTask)的输出进行 partition,不同的 partition 送到不同的 reducer(Spark 里 reducer 可能是下一个 stage 里的ShuffleMapTask,也可能是 ResultTask)。Reducer 以内存作缓冲区,边shuffle 边 aggregate 数据,等到数据 aggregate 好以后进行 reduce()(Spark 里可能是后续的一系列操作)。


2)从 low-level 的角度来看,两者差别不小。 Hadoop MapReduce 是sort-based,进入 combine() 和 reduce() 的 records 必须先 sort。这样的好处在于 combine/reduce() 可以处理大规模的数据,因为其输入数据可以通过外排得到(mapper 对每段数据先做排序,reducer 的 shuffle 对排好序的每段数据做归并)。


目前的 Spark 默认选择的是 hash-based,通常使用HashMap 来对 shuffle 来的数据进行 aggregate,不会对数据进行提前排序。如果用户需要经过排序的数据,那么需要自己调用类似 sortByKey() 的操作; 如果你是 Spark 1.1 的用户,可以将 spark.shuffle.manager 设置为 sort,则会对数据进行排序。在 Spark 1.2 中,sort 将作为默认的 Shuffle 实现。


3)从实现角度来看,两者也有不少差别。 Hadoop MapReduce 将处理流程划分出明显的几个阶段:map(), spill, merge, shuffle, sort, reduce() 等。每个阶段各司其职,可以按照过程式的编程思想来逐一实现每个阶段的功能。在 Spark 中,没有这样功能明确的阶段,只有不同的 stage 和一系列的transformation(),所以 spill, merge, aggregate 等操作需要蕴含在transformation() 中。


如果我们将 map 端划分数据、持久化数据的过程称为 shuffle write,而将reducer 读入数据、aggregate 数据的过程称为 shuffle read。那么在 Spark 中,问题就变为怎么在 job 的逻辑或者物理执行图中加入 shuffle write 和shuffle read 的处理逻辑?以及两个处理逻辑应该怎么高效实现?


Shuffle write 由于不要求数据有序,shuffle write 的任务很简单:将数据partition 好,并持久化。之所以要持久化,一方面是要减少内存存储空间压力, 另一方面也是为了 fault-tolerance。


蓝海大脑 京ICP备18017748号-1