Spark-Sort排序详解

来源:互联网 发布:读取class属性 php 编辑:程序博客网 时间:2024/06/05 04:48

目录(?)[+]

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
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  1. val rdd2=rdd1.sortBy(f=>(f._1,f._3)).collect  
看上去是不是很神奇,其实sortBy内部帮我们做的,就是我上面写的代码。下面看下SortBy的源码:
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  1. def top(num: Int)(implicit ord: Ordering[T]): Array[T] = withScope {  
  2.     takeOrdered(num)(ord.reverse)  
  3.   }  
在下面的元组中,以第2个元素基,取出前3大的元组
[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  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
 在CODE上查看代码片派生到我的代码片
  1. result: Array[(Int, Int, Int)] = Array((2,6,3), (1,5,4), (1,3,3))  
0 0
原创粉丝点击