背景
在理解在混洗(shuffle)之间发生了什么,我们考虑reduceByKey操作的例子。reduceByKey操作产生了一个新的RDD,对于同一个key,它所有的value都被结合到一个tuple中--key和与此key对应的所有values执行一个reduce函数之后的结果。这个挑战不是说,对于一个key的所有values应该在同一个分区或者甚至同一台机器,而是他们必须被同地协作(co-located)以计算结果。
在Spark看,对于一个指定的操作,数据通常不是分发各个分区到必要的地方。在计算期间,单个任务将操作一个分区--因此,对于单个reduceByKey的reduce任务,要组织所有的数据来执行reduce,Spark需要一个all-toall的操作。它必须读取来自所有的分区以找到所有的key,所对应的所有的values,然后跨越分区计算每个key的最终结果,并把values放到一起--这被称为混洗(shuffle)。
尽管混洗后的数据的每个分区的元素集合被确定,且是按分区自己进行了排序,这些元素是没有排序的。如果渴望在混洗后,得到预期排序的数据,可以这样使用:
mapPartitions
来对每个分区进行排序, 例如, .sortedrepartitionAndSortWithinPartitions
来进行有效的分区排序,且同时重新分区。sortBy
来做一个全局的RDD排序
会引起一个混洗的操作包括重新分区操作,如repartition和coalesce,‘ByKey操作(除了counting),如groupByKey和reduceByKey,和join操作,如cogroup和join。