需求:将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. sql 当重复的数据有多条时,保留一条,删除其他重复

    delete from proj_info where   newcode in (select newcode    from proj_info group by newcode      hav ...

  2. 1106关于解决erp单个商品同步的问题

    1.断点测试: 不断的利用echo "<pre>"; print_r();die;来测试问题出在哪? 先找问题出错点,再找出具体的细节. --------------- ...

  3. mysql时间int日期转换

    select from_unixtime(1350437720);select unix_timestamp(now());插入用 unix_timestamp(date)查询用from_unixti ...

  4. var genreModel =storeDB.Genres.Include("Albums").Single(g => g.Name == genre);是什么意思?

    g => g.Name == genre代表一个匿名函数.即这里向Single方法传入了一个方法类型的参数. =>左边的g代表方法的参数,可以有多个,如(g,f) => ...,=& ...

  5. UCOS 杂项 笔记

    1.  建立任务和建立数据队列  哪个先建立? 经过试验得知,数据队列和任务的建立先后没有顺序,都可以正常运行. 2.关于主函数的面试问题. 主函数写法有:   int  main()    和voi ...

  6. d007: 求两数的整数商 和 余数

    内容: 求两数的整数商 和 余数 输入说明: 一行两个整数 输出说明: 一行两个整数 输入样例:   18 4 输出样例 : 4 2 #include <stdio.h> int main ...

  7. PHP开发环境设置

    步骤有三个: Apache 服务器安装.PHP 安装和让 Apache 支持 PHP 1. Apache 服务器的安装与配置 基于Windows操作系统支持的PHP开发的服务器有IIS和Apache, ...

  8. IOS之动画

    IOS之动画   15.1 动画介绍 15.2 Core Animation基础 15.3 隐式动画 15.4 显式动画 15.5 关键帧显式动画 15.6 UIView级别动画 15.1 动画介绍 ...

  9. Web前端开发

    由于互联网的各种兴起,网页开发似乎也火了,催生了github上各种js的轮子,各种重复,各种框架和库,什么Jquery,bootstrap等等.面对这么多框架和库我们在工程上该如何取舍(trade-o ...

  10. curl 提交请求

    http://forums.phpfreaks.com/topic/194255-curl-sending-array-as-post-value/ http://www.cnblogs.com/ch ...