需求:将rdd数据中相同班级的学生分到一个partition中,并根据分数降序排序。

此实例用到的repartitionAndSortWithinPartitions是Spark官网推荐的一个算子,官方建议,如果需要在repartition重分区之后,还要进行排序,建议直接使用repartitionAndSortWithinPartitions算子。因为该算子可以一边进行重分区的shuffle操作,一边进行排序。shuffle与sort两个操作同时进行,比先shuffle再sort来说,性能可能是要高的。

import org.apache.spark.{SparkContext, SparkConf}

/**
* Created by sunxufeng on 2016/6/18.
*/
class Student { } //创建key类,key组合键为grade,score
case class StudentKey(grade:String,score:Int)
// extends Ordered[StudentKey]{
// def compare(that: StudentKey) : Int = {
// var result:Int = this.grade.compareTo(that.grade)
// if (result == 0){
// result = this.student.compareTo(that.student)
// if(result ==0){
// result = that.score.compareTo(this.score)
// }
// }
// result
// }
//} object StudentKey {
implicit def orderingByGradeStudentScore[A <: StudentKey] : Ordering[A] = {
// Ordering.by(fk => (fk.grade, fk.student, fk.score * -1))
Ordering.by(fk => (fk.grade, fk.score * -1))
}
} object Student{
def main(args: Array[String]) { //定义hdfs文件索引值
val grade_idx:Int=0
val student_idx:Int=1
val course_idx:Int=2
val score_idx:Int=3 //定义转化函数,不能转化为Int类型的,给默认值0
def safeInt(s: String): Int = try { s.toInt } catch { case _: Throwable => 0 } //定义提取key的函数
def createKey(data: Array[String]):StudentKey={
StudentKey(data(grade_idx),safeInt(data(score_idx)))
} //定义提取value的函数
def listData(data: Array[String]):List[String]={
List(data(grade_idx),data(student_idx),data(course_idx),data(score_idx))
} def createKeyValueTuple(data: Array[String]) :(StudentKey,List[String]) = {
(createKey(data),listData(data))
} //创建分区类
import org.apache.spark.Partitioner
class StudentPartitioner(partitions: Int) extends Partitioner {
require(partitions >= 0, s"Number of partitions ($partitions) cannot be negative.") override def numPartitions: Int = partitions override def getPartition(key: Any): Int = {
val k = key.asInstanceOf[StudentKey]
k.grade.hashCode() % numPartitions
}
} //设置master为local,用来进行本地调试
val conf = new SparkConf().setAppName("Student_partition_sort").setMaster("local")
val sc = new SparkContext(conf) //学生信息是打乱的
val student_array =Array(
"c001,n003,chinese,59",
"c002,n004,english,79",
"c002,n004,chinese,13",
"c001,n001,english,88",
"c001,n002,chinese,10",
"c002,n006,chinese,29",
"c001,n001,chinese,54",
"c001,n002,english,32",
"c001,n003,english,43",
"c002,n005,english,80",
"c002,n005,chinese,48",
"c002,n006,english,69"
)
   //将学生信息并行化为rdd
val student_rdd = sc.parallelize(student_array)
   //生成key-value格式的rdd
val student_rdd2 = student_rdd.map(line => line.split(",")).map(createKeyValueTuple)
//根据StudentKey中的grade进行分区,并根据score降序排列
val student_rdd3 = student_rdd2.repartitionAndSortWithinPartitions(new StudentPartitioner(10))
   //打印数据
student_rdd3.collect.foreach(println)
}
}

排序后的数据:

(StudentKey(c001,88),List(c001, n001, english, 88))
(StudentKey(c001,59),List(c001, n003, chinese, 59))
(StudentKey(c001,54),List(c001, n001, chinese, 54))
(StudentKey(c001,43),List(c001, n003, english, 43))
(StudentKey(c001,32),List(c001, n002, english, 32))
(StudentKey(c001,10),List(c001, n002, chinese, 10))
(StudentKey(c002,80),List(c002, n005, english, 80))
(StudentKey(c002,79),List(c002, n004, english, 79))
(StudentKey(c002,69),List(c002, n006, english, 69))
(StudentKey(c002,48),List(c002, n005, chinese, 48))
(StudentKey(c002,29),List(c002, n006, chinese, 29))
(StudentKey(c002,13),List(c002, n004, chinese, 13))

参考:http://codingjunkie.net/spark-secondary-sort/

RDD 重新分区,排序 repartitionAndSortWithinPartitions的更多相关文章

  1. RDD(六)——分区器

    RDD的分区器 Spark目前支持Hash分区和Range分区,用户也可以自定义分区,Hash分区为当前的默认分区,Spark中分区器直接决定了RDD中分区的个数.RDD中每条数据经过Shuffle过 ...

  2. Spark RDD概念学习系列之Pair RDD的分区控制

    不多说,直接上干货! Pair RDD的分区控制 Pair RDD的分区控制 (1) Spark 中所有的键值对RDD 都可以进行分区控制---自定义分区 (2)自定义分区的好处:  1) 避免数据倾 ...

  3. SQLServer ROW_NUMBER()函数使用方法 分区排序

    #ROW_NUMBER() over()能干什么? 既可满足分区的需求,也可以根据一定的顺序来排序. #细细说 select ROW_NUMBER() over(partition by xm Ord ...

  4. Mybatis中选择语句的使用:<choose>标签、分区排序 Row_num() over ()函数的使用呢

    1.Mybatis中数据库语句的选择 使用: <choose>       <when test="relationType=='L'">          ...

  5. Spark(九)【RDD的分区和自定义Partitioner】

    目录 spark的分区 一. Hash分区 二. Ranger分区 三. 自定义Partitioner 案例 spark的分区 ​ Spark目前支持Hash分区和Range分区,用户也可以自定义分区 ...

  6. 查看spark RDD 各分区内容

    mapPartitionsWithIndexdef mapPartitionsWithIndex[U](f: (Int, Iterator[T]) => Iterator[U], preserv ...

  7. Spark RDD 默认分区数量 - repartitions和coalesce异同

    RDD.getNumPartitions()方法可以获得一个RDD分区数量, 1.默认由文件读取的话,本地文件会进行shuffle,hdfs文件默认会按照dfs分片来设定. 2.计算生成后,默认会按照 ...

  8. RDD的分区相关

    分区是rdd的一个属性,每个分区是一个迭代器 分区器是决定数据数据如何分区 RDD划分成许多分区分布到集群的节点上,分区的多少涉及对这个RDD进行并行计算的粒度.用户可以获取分区数和设置分区数目,默认 ...

  9. sqlserver 分区排序之partition

    例如:按照课程分组取各个课程最高成绩的记录,使用partition分区,然后按照成绩倒序排列,需要注意的是考虑到可能出现多个相同最高分,使用dense_rank来实现连续排序. 参考链接:https: ...

随机推荐

  1. Menu之选项菜单

    Android有三种形式的菜单:选项菜单(optionMenu).上下文菜单(ContextMenu).子菜单(subMenu).最常用的是选项菜单,该菜单在点击menu按键后会在对应的Activit ...

  2. GET——token

    private function get_token(){ $appid="wx4dae5d61b7f9935c"; $appSecret="24a91315a1a62a ...

  3. Spring4.0学习笔记(1) —— 基础知识

    1.基本定义 IOC: 其思想是反转资源获取的方向,传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源,而应用了 IOC之后,容器主动将资源推送给它所管理的组件,组件索要做 ...

  4. arclist标签和list标签区别

    很多站长朋友在刚入门织梦的时候对织梦的标签存在很多的困惑,关于arclist标签和list标签,甚至不知道啥时候用arclist,啥时用list标签.arclist 为自由列表,全局模板中都生效,一般 ...

  5. C# 实现将PDF转文本的功能

    这篇文章最初只描述使用 PDFBox 来解析PDF文件.现在它已经被扩展到包括使用 IFilter 和 iTextSharp 的例程了.  这篇文章和对应的Visual Studio项目已经更新到目前 ...

  6. 《python基础教程》笔记之 其它语句1

    print 相关 print可以打印多个表达式,只要将它们用逗号隔开就好,结果中每个参数之间都会插入一个空格,使用+可以避免空格,如 >>> print 'age:',42age: ...

  7. RSA 加密

    iOS开发教程-iOS中的RSA加解密 在移动应用开发中常常遇到数据传输安全性的问题,尤其是在账户安全以及支付场景中的订单数据.或支付信息的传输中,正规的公司一定会要求对数据进行加密,当然有创业初期的 ...

  8. MFC动态创建按钮,并在按钮上实现位图的切换显示

    动态创建按钮,并在按钮中添加位图,通过单击按钮显示不同的位图,可设置为显示按钮按下和弹起两种状态.只要判断a值从而输入不同的响应代码. 1.在头文件中添加: CButton *pBtn; 2.在初始化 ...

  9. BZOJ3410: [Usaco2009 Dec]Selfish Grazing 自私的食草者

    3410: [Usaco2009 Dec]Selfish Grazing 自私的食草者 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 47  Solve ...

  10. BZOJ1690: [Usaco2007 Dec]奶牛的旅行

    1690: [Usaco2007 Dec]奶牛的旅行 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 552  Solved: 286[Submit][St ...