spark: 二次排序-2
在上一篇文章,使用了###错误###的方法实现二次排序,导致排序按key字典排序,并非我们想要的结果
现在,使用自定义排序方法来实现二次排序
1, 思路
输入数据
aa 12
bb 32
aa 3,
cc 43
dd 23
cc 5
cc 8
bb 23
bb 12
-
自定义排序类:对二元组(key:String, value:Int)进行排序
-
把每一行数据map成二元组(key:String, value:Int)
-
排序 -- scala自动使用步骤1定义的排序类进行排序
/** * 1. 自定义排序类:对二元组(key:String, value:Int)进行排序 */ class KVOrdering extends Ordering[Tuple2[String, Int]] with Serializable { override def compare(x: Tuple2[String, Int], y: Tuple2[String, Int]):Int = { val comp = x._1.compareTo(y._1) if (comp == 0) { // key相等, 则比较value x._2.compareTo(y._2) } else { comp } } }
由于scala的隐式转换机制,这个类会对闭包内的所有Tuple2[String, Int]产生作用
val inputFile = sc.textFile("/home/hadoop/second_sort")
// 2. 把每一行数据map成二元组(key:String, value:Int)
val splitRdd = inputFile.map{x=>val y = x.split(' '); (y(0), Integer.valueOf(y(1)))}
// 3. 排序
val sortedRdd = splitRdd.sortBy(x=>x)
3 后记
-
自定义排序类需要继承 com.google.common.collect.Ordering, 这个类在guava.jar, 测试的时候需要导入这个包。如果是在shell测试,使用下面的命令
bin/spark-shell --jars "PATH_TO_GUAVA"
-
这个方法忽略了一个事实:9park中, RDD是可分区的。现在我们只针对一个RDD的一个分区来做排序。RDD的多个分区,在多个worker node上并行排序,产生多个结果集,如何对这些结果集最后做一次归并排序?后面的文章再继续分析9这个问题