RDD 重新分区,排序 repartitionAndSortWithinPartitions
需求:将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的更多相关文章
- RDD(六)——分区器
RDD的分区器 Spark目前支持Hash分区和Range分区,用户也可以自定义分区,Hash分区为当前的默认分区,Spark中分区器直接决定了RDD中分区的个数.RDD中每条数据经过Shuffle过 ...
- Spark RDD概念学习系列之Pair RDD的分区控制
不多说,直接上干货! Pair RDD的分区控制 Pair RDD的分区控制 (1) Spark 中所有的键值对RDD 都可以进行分区控制---自定义分区 (2)自定义分区的好处: 1) 避免数据倾 ...
- SQLServer ROW_NUMBER()函数使用方法 分区排序
#ROW_NUMBER() over()能干什么? 既可满足分区的需求,也可以根据一定的顺序来排序. #细细说 select ROW_NUMBER() over(partition by xm Ord ...
- Mybatis中选择语句的使用:<choose>标签、分区排序 Row_num() over ()函数的使用呢
1.Mybatis中数据库语句的选择 使用: <choose> <when test="relationType=='L'"> ...
- Spark(九)【RDD的分区和自定义Partitioner】
目录 spark的分区 一. Hash分区 二. Ranger分区 三. 自定义Partitioner 案例 spark的分区 Spark目前支持Hash分区和Range分区,用户也可以自定义分区 ...
- 查看spark RDD 各分区内容
mapPartitionsWithIndexdef mapPartitionsWithIndex[U](f: (Int, Iterator[T]) => Iterator[U], preserv ...
- Spark RDD 默认分区数量 - repartitions和coalesce异同
RDD.getNumPartitions()方法可以获得一个RDD分区数量, 1.默认由文件读取的话,本地文件会进行shuffle,hdfs文件默认会按照dfs分片来设定. 2.计算生成后,默认会按照 ...
- RDD的分区相关
分区是rdd的一个属性,每个分区是一个迭代器 分区器是决定数据数据如何分区 RDD划分成许多分区分布到集群的节点上,分区的多少涉及对这个RDD进行并行计算的粒度.用户可以获取分区数和设置分区数目,默认 ...
- sqlserver 分区排序之partition
例如:按照课程分组取各个课程最高成绩的记录,使用partition分区,然后按照成绩倒序排列,需要注意的是考虑到可能出现多个相同最高分,使用dense_rank来实现连续排序. 参考链接:https: ...
随机推荐
- impdp/expdp 总结
impdp/expdp 1.创建DIRECTORY create directory dir_dp as '/tmp'; --建议将DIRECTORY 建在 /tmp 表下面,该目录肯定存 ...
- centos 下使用sublime
CentOS 之 Sublime text3 安装及配置(不支持中文输入) sublime text 的界面友好,自动补全功能也不错. (本来用vim+php_function.txt的形式进行补全的 ...
- fabric自动化部署django
使用fabric部署django应用 使用fabric部署django应用 本文是我的网站易读中文网自动化部署的脚本实现,以下代码在ubuntu和debian中测试通过 由于网站使用的是python技 ...
- IRP派遣操作
IRPTrace工具跟踪IRP 派遣函数(Dispathc Funtion)是windows驱动中的重要概念.驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的.用户模式 ...
- navicat:cannot create oci environment
1.请注意红色箭头处的配置是从oracle官网下载的安装包 ,当然百度也是很强大的.(建议是在navicat安装目录下解压) 2.红色方框内的是你本地的oracle数据库的sqlplus.exe启动地 ...
- Linux里面怎样修改主机名
第一步:hostname 修改后的主机名 第二步:修改/etc/sysconfig/network中的hostname第三步:修改/etc/hosts文件 示例: 我机器现在的主机名是pc,想修改成t ...
- 两段小PYTHON,作啥用的,行内人才懂~~~:(
哎,作也不是,不作也不是.... 下次有更新文件时,直接刷新一次了. #coding: UTF-8 import sys reload(sys) sys.setdefaultencoding( &qu ...
- Smarty 使用继承方式实现配置
. 常用配置选项 在使用Smarty模板引擎之前,我们必须先学习如何配置Smarty的选项.而在Smarty的常见选项中,我们首先必须了解4个最基本的目录选项. 模板目录(template):本目录用 ...
- rsyslog imfile 模块说明
stop() { echo -n $"Shutting down system logger: " killproc -p "${PIDFILE}" -d 30 ...
- vsftpd,tftp安装配置
一. 对比共同点:都包含ftp不同点:1)vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序.你可以通过ftp客户端上传下载软件.可设置访问用户名密码,或匿名anonymous登陆.默认 ...