Spark核心RDD:Sort排序詳解

1.sortByKey

無可非議sortByKey是Spark的最常用的排序,簡單的案例暫且跳過,下面給一個非簡單的案例,進入排序之旅
對下面簡單元祖,要求先按元素1升序,若元素1相同,則再按元素3升序


(1, 6, 3), (2, 3, 3), (1, 1, 2), (1, 3, 5), (2, 1, 2)
提示:sortByKey對於key是單個元素排序很簡單,如果key是元組如(X1,X2,X3.....),它會先按照X1排序,若X1相同,則在根據X2排序,依次類推...
由上面的分析,我們可以給出如下的代碼:
[java] view plain copy
  1. val conf = new SparkConf()  
  2. val sc = new SparkContext(conf)  
  3. val array = Array((163), (233), (112), (135), (212))  
  4. val rdd1 = sc.parallelize(array)  
  5. //設置元素(e1,e3)爲key,value爲原來的整體  
  6. val rdd2 = rdd1.map(f => ((f._1, f._3), f))  
  7. //利用sortByKey排序的對key的特性  
  8. val rdd3 = rdd2.sortByKey()  
  9. val rdd4 = rdd3.values.collect  
結果:
[java] view plain copy
  1. rdd4: Array[(Int, Int, Int)] = Array((1,1,2), (1,6,3), (1,3,5), (2,1,2), (2,3,3))  

2.sortBy

SortBy其實是SortBykey的加強版,比如上面的功能可以使用這個函數實現
[java] view plain copy
  1. val rdd2=rdd1.sortBy(f=>(f._1,f._3)).collect  
看上去是不是很神奇,其實sortBy內部幫我們做的,就是我上面寫的代碼。下面看下SortBy的源碼:
[java] view plain copy
  1. def sortBy[K](  
  2.      f: (T) => K,  
  3.      ascending: Boolean = true,  
  4.      numPartitions: Int = this.partitions.length)  
  5.      (implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T] = withScope {  
  6.    this.keyBy[K](f)  
  7.        .sortByKey(ascending, numPartitions)  
  8.        .values  
  9.  }  
sortBy先調用keyBy函數,而keyBy的功能很簡單,key爲用戶制定,比如上面的f => ((f._1, f._3),value爲原始值:
[java] view plain copy
  1. def keyBy[K](f: T => K): RDD[(K, T)] = withScope {  
  2.    val cleanedF = sc.clean(f)  
  3.    map(x => (cleanedF(x), x))  
  4.  }  
最後在調用sortByKey函數,和上面的神似有木有..

3.Ordering

Ordering在Spark的排序應用中隨處可見,比如上面的SortBy它就有一個隱式參數implicit ord: Ordering[K],如下摘抄自Scala提供AIP
對簡單的類型排序, quickSort 這裏使用了高階函數的柯里化,  爲第二個括號爲Ordering類型的隱式參數
[java] view plain copy
  1. import scala.util.Sorting  
  2. val pairs = Array(("a"52), ("c"31), ("b"13))  
  3. // sort by 2nd element  
  4. Sorting.quickSort(pairs)(Ordering.by[(String, Int, Int), Int](_._2))  
  5. // sort by the 3rd element, then 1st  
  6. Sorting.quickSort(pairs)(Ordering[(Int, String)].on(x => (x._3, x._1)))  
對複雜類型的排序
[java] view plain copy
  1. import scala.util.Sorting  
  2. case class Person(name:String, age:Int)  
  3. val people = Array(Person("bob"30), Person("ann"32), Person("carl"19))  
  4. // sort by age  
  5. object AgeOrdering extends Ordering[Person] {  
  6.   def compare(a:Person, b:Person) = a.age compare b.age  
  7. }  
  8. Sorting.quickSort(people)(AgeOrdering)  

因爲sortByKey實現了Ordering的很多功能,下面以Spark中的top函數爲例
[java] view plain copy
  1. def top(num: Int)(implicit ord: Ordering[T]): Array[T] = withScope {  
  2.     takeOrdered(num)(ord.reverse)  
  3.   }  
在下面的元組中,以第2個元素基,取出前3大的元組
[java] view plain copy
  1. val array = Array((133), (263), (112), (154), (212))  
  2. val rdd1 = sc.parallelize(array)  
  3. val result=rdd1.top(3)(Ordering.by[(Int, Int, Int), Int](_._2))  
結果:
[java] view plain copy
  1. result: Array[(Int, Int, Int)] = Array((2,6,3), (1,5,4), (1,3,3))  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章