Spark的TopN解决方案(键唯一的情况、键不唯一的情况)
来源:互联网 发布:suse linux下载 编辑:程序博客网 时间:2024/06/06 20:55
TopN问题:上星期访问次数最多的10个URL是哪些?所有猫中体重最大的10只猫是哪些?
本文使用 MapReduce/Hadoop的TopN解决方案,假设所有输入键都是唯一的。也就是说,对于一个给定的输入集合{<K,V>},所有K都是唯一的。
例如对于下面的猫,cat1不会再出现第二次
输入:
top10data.txt
cat1,12cat2,13cat3,14cat4,15cat5,10cat100,100cat200,200cat300,300cat1001,1001cat67,67cat22,22cat23,23cat1000,1000cat2000,2000cat400,400cat500,500
cat8,8cat9,9cat7,7cat6,6cat450,450cat350,350cat150,150cat3000,3000cat1500,1500cat1601,1601cat201,201cat222,222
Spark解决方案:使用mapPartitions()函数对每一个分区求top10(),最后使用collect()创建最终的top10列表
键唯一的情况:
//导入必要的类import java.util.{SortedMap, TreeMap}import akka.io.Udp.SO.Broadcastimport org.apache.spark.rdd.RDDimport org.apache.spark.{SparkConf, SparkContext}object TopN_1 { def main(args: Array[String]): Unit = { //连接SparkMaster val conf = new SparkConf().setAppName("Chenjie's first spark App").setMaster("local") val sc = new SparkContext(conf) //从HDFS中读取输入文件并创建RDD val lines = sc.textFile("hdfs://pc1:9000/input/top10data*.txt") lines.foreach(println)//输出观察 val broadcastTopN = sc.broadcast[Integer](10)//指定TopN的N值 val broadcastDirection = sc.broadcast("top")//指定取最大的还是最小的,top/bottom val pairs = lines.map { line => val tokens = line.split(",") (tokens(0), tokens(1).toInt) }//将每一行按照猫名和体重分开,并映射为以猫名为key,体重为value的键值对 val partitions:RDD[SortedMap[Integer, String]] = pairs.mapPartitions {iter => //对于每一个分区应用map println("-----------------------开始处理一个分区---------------------------") import scala.collection.mutable.ArrayBuffer val arrayBuffer = ArrayBuffer[SortedMap[Integer, String]]() var top10: SortedMap[Integer, String] = new TreeMap[Integer, String]()//为各输入分区创建一个本地top10列表 while (iter.hasNext) { val tuple = iter.next top10.put(tuple._2, tuple._1) if (top10.size() > broadcastTopN.value) { if(broadcastDirection.value.equals("top")) top10.remove(top10.firstKey()) else top10.remove(top10.lastKey()) } } arrayBuffer += (top10) println("这个分区的top10如下:") arrayBuffer.foreach(println) arrayBuffer.iterator } var finaltop10: SortedMap[Integer, String] = new TreeMap[Integer, String]() val alltop10:Array[SortedMap[Integer, String]] = partitions.collect()//使用collect()创建最终的top10列表 for(localtop10:SortedMap[Integer, String] <- alltop10){ localtop10.entrySet().toArray.foreach{entry=> finaltop10.put(entry.toString.split("=")(0).toInt,entry.toString.split("=")(1)) if(finaltop10.size() > 10){ finaltop10.remove(finaltop10.firstKey()) } } } println("总的top10如下:") finaltop10.entrySet().toArray().foreach(println) }}
键不唯一的情况:仅仅只需要对键值对集合运用reduceByKey操作即可
//导入必要的类import java.util.{SortedMap, TreeMap}import akka.io.Udp.SO.Broadcastimport org.apache.spark.rdd.RDDimport org.apache.spark.{SparkConf, SparkContext}object TopN_1 { def main(args: Array[String]): Unit = { //连接SparkMaster val conf = new SparkConf().setAppName("Chenjie's first spark App").setMaster("local") val sc = new SparkContext(conf) //从HDFS中读取输入文件并创建RDD val lines = sc.textFile("hdfs://pc1:9000/input/top10data*.txt") lines.foreach(println)//输出观察 val broadcastTopN = sc.broadcast[Integer](10)//指定TopN的N值 val broadcastDirection = sc.broadcast("top")//指定取最大的还是最小的,top/bottom val pairs = lines.map { line => val tokens = line.split(",") (tokens(0), tokens(1).toInt) }//将每一行按照猫名和体重分开,并映射为以猫名为key,体重为value的键值对 val partitions:RDD[SortedMap[Integer, String]] = pairs.reduceByKey(_+_).mapPartitions {iter => //对于每一个分区应用map println("-----------------------开始处理一个分区---------------------------") import scala.collection.mutable.ArrayBuffer val arrayBuffer = ArrayBuffer[SortedMap[Integer, String]]() var top10: SortedMap[Integer, String] = new TreeMap[Integer, String]()//为各输入分区创建一个本地top10列表 while (iter.hasNext) { val tuple = iter.next top10.put(tuple._2, tuple._1) if (top10.size() > broadcastTopN.value) { if(broadcastDirection.value.equals("top")) top10.remove(top10.firstKey()) else top10.remove(top10.lastKey()) } } arrayBuffer += (top10) println("这个分区的top10如下:") arrayBuffer.foreach(println) arrayBuffer.iterator } var finaltop10: SortedMap[Integer, String] = new TreeMap[Integer, String]() val alltop10:Array[SortedMap[Integer, String]] = partitions.collect()//使用collect()创建最终的top10列表 for(localtop10:SortedMap[Integer, String] <- alltop10){ localtop10.entrySet().toArray.foreach{entry=> finaltop10.put(entry.toString.split("=")(0).toInt,entry.toString.split("=")(1)) if(finaltop10.size() > 10){ finaltop10.remove(finaltop10.firstKey()) } } } println("总的top10如下:") finaltop10.entrySet().toArray().foreach(println) }}
此外,还可以用takeOrdered()方法实现
//导入必要的类import java.util.{SortedMap, TreeMap}import akka.io.Udp.SO.Broadcastimport org.apache.spark.rdd.RDDimport org.apache.spark.{SparkConf, SparkContext}object TopN_1 { def main(args: Array[String]): Unit = { //连接SparkMaster val conf = new SparkConf().setAppName("Chenjie's first spark App").setMaster("local") val sc = new SparkContext(conf) //从HDFS中读取输入文件并创建RDD val lines = sc.textFile("hdfs://pc1:9000/input/top10data*.txt") lines.foreach(println) //输出观察 val broadcastTopN = sc.broadcast[Integer](10) //指定TopN的N值 val broadcastDirection = sc.broadcast("top") //指定取最大的还是最小的,top/bottom val pairs = lines.map { line => val tokens = line.split(",") (tokens(0), tokens(1).toInt) } //将每一行按照猫名和体重分开,并映射为以猫名为key,体重为value的键值对 pairs.reduceByKey(_ + _).takeOrdered(10)(new Ordering[(String,Int)]{ override def compare(x: (String, Int), y: (String, Int)): Int = - x._2.compareTo(y._2) }).foreach(println) }}
阅读全文
0 0
- Spark的TopN解决方案(键唯一的情况、键不唯一的情况)
- MapReduce/Hadoop的TopN解决方案之键唯一的情况
- MapReduce/Hadoop的TopN解决方案之键不唯一的情况
- 分布式情况下生成数据库唯一ID的解决方案
- MySQL在右表数据不唯一的情况下使用left join的方法
- Caused by: org.apache.ibatis.reflection.ReflectionException我碰到的情况,原因不唯一
- mysql left join 右表数据不唯一的情况解决方法
- mysql left join 右表数据不唯一的情况解决方法
- java中自定义异常和finally唯一不执行的情况
- mysql left join 右表数据不唯一的情况解决方法
- mysql left join 右表数据不唯一的情况解决方法
- mysql left join 右表数据不唯一的情况解决方法
- CC2530的特殊情况吧,也可能使唯一的。
- 使用Hadoop和Spark实现TopN算法(1)——唯一键
- 表中已存重复数据的情况,如何增加唯一性约束?
- 在没有用户ID或者任何唯一性标识的情况下做个唯一标识
- MySQL InnoDB中唯一索引和非唯一索引时的加锁情况
- 唯一索引的索引键不保存rowid
- 问题 D: 沙漏图形 tri2str [1*+]
- leetcode 216
- 二进制包安装MySQL过程中遇到的一系列错误
- 设计模式梳理(一)
- 数据结构之链表面试题汇总(一)--查找单向链表的中间节点、倒数第K个节点
- Spark的TopN解决方案(键唯一的情况、键不唯一的情况)
- 图像处理基础知识
- Java 把char型 '9'转换成int型 9
- 第八周项目四 稀疏矩阵的三元组表示的实现与应用(2)
- 11月2日
- Mvp
- [洛谷]P3371 单源最短路径模板-bell
- 二叉树的前序,中序,后序遍历
- 机器学习基础之学习方式