该函数主要功能:通过指定的排序规则与进行排序操作的分区个数,对当前的RDD中的数据集按KEY进行排序,并生成一个SHUFFLEdrdd的实例,这个过程会执行shuffle操作,在执行排序操作前,sortBy操作会执行一次到两次的数据取样的操作,取出RDD中每个PARTITION的部分数据,并根据进行分区的partition的个数,按key的compare大小把某个范围内的key放到一个指定的partition中进行排序.
该函数的操作示例:
import org.apache.spark.SparkContext._
*
* val rdd: RDD[(String, Int)] = ...
* implicit val caseInsensitiveOrdering = new Ordering[String] {
* override def compare(a: String, b: String) =
a.toLowerCase.compare(b.toLowerCase)
* }
*
* // Sort by key, using the above case insensitive ordering.
* rdd.sortByKey()
这上面的示例中定义implicit的隐试转换,
在OrderedRDDFunctions通过private val ordering = implicitly[Ordering[K]]引用
函数定义,由OrderedRDDFunctions类进行函数的实现:
这个函数中,传入两个参数,ascending表示是升序还是降序,默认true表示升序.
第二个参数是执行排序使用的partition的个数,默认是当前RDD的partition个数.
def sortByKey(ascending: Boolean = true, numPartitions: Int = self.partitions.length)
: RDD[(K, V)] = self.withScope
{
生成执行分区操作的算子,这里生成的算子不再是默认的Hash算子,而是Range的算子,这个算子后面进行具体的分析.
val part = new RangePartitioner(numPartitions, self, ascending)
这里重新根据当前的RDD,生成一个新的RDD,这个shuffle的rdd中,不包含aggregator聚合函数.
也就是在shuffle的过程中只是把key对应的值hash到对应的partition中,并根据key执行排序操作.
new ShuffledRDD[K, V, V](self, part)
.setKeyOrdering(if (ascending) ordering else ordering.reverse)
}
接下来看看RangePartitioner的排序算子的实现