大家好,我是风云,欢迎大家关注我的个人原创公众号【笑看风云路】获取更多大数据技术干货,在未来的日子里我们一起来学习大数据相关的技术,一起努力奋斗,遇见更好的自己!
扫码进,更快捷:
在实际开发过程中,我们会经常碰到求TopN这样常见的需求,那在Spark中,是如何实现求TopN呢?带着这个问题,就来看一下TopN的实现方式都有哪些!
思路:
按照key对数据进行聚合(groupByKey)
对同组的key的所有value先转换为List,然后进行排序,最后取TopN
代码实现:
// 构造上下文
val conf = new SparkConf().setMaster("local").setAppName("topn")
val sc = SparkContext.getOrCreate(conf)
// 创建rdd
val path = "datas/groupsort.txt"
val rdd = sc.textFile(path)
// rdd操作得出结果
val rdd2 = rdd.map(_.split(" "))
val result = rdd2.map(arr => (arr(0).trim, arr(1).trim.toInt))
.groupByKey()
.map {
case (key, values) => {
// 对values中的数据进行排序,然后获取最大的前三个数据
val sortedValues = values.toList.sorted
val top3Values = sortedValues.takeRight(3).reverse
(key, top3Values)
}
}
// 打印输出
result.collect().foreach(println)
sc.stop()
思路:
代码实现:
// 构造上下文
val conf = new SparkConf().setMaster("local").setAppName("topn")
val sc = SparkContext.getOrCreate(conf)
// 创建rdd
val path = "datas/groupsort.txt"
val rdd = sc.textFile(path)
// rdd操作得出结果
val rdd2 = rdd.map(_.split(" "))
val result = rdd2.mapPartitions(iter => {
val random = Random
iter.map(arr => {
val key = arr(0).trim
val value = arr(1).trim.toInt
((random.nextInt(5),key),value)
})
}).groupByKey()
.flatMap{
case ((_,key),values) => {
val sortedValues = values.toList.sorted
val top3Values = sortedValues.takeRight(3).reverse
top3Values.map(count => (key,count))
}
}
.groupByKey()
.flatMap{
case (key, values) => {
val sortedValues = values.toList.sorted
val top3Values = sortedValues.takeRight(3).reverse
top3Values.map((key,_))
}
}
// 打印输出
result.collect().foreach(println)
sc.stop()
思路:
代码实现:
// 构造上下文
val conf = new SparkConf().setMaster("local").setAppName("topn")
val sc = SparkContext.getOrCreate(conf)
// 创建rdd
val path = "datas/groupsort.txt"
val rdd = sc.textFile(path)
// rdd操作得出结果
val rdd2 = rdd.map(_.split(" "))
val result3 = rdd2.map(arr => {
val key = arr(0).trim
val count = arr(1).trim.toInt
(key, count)
})
.mapPartitions(iter => {
import scala.collection.mutable
val temp = iter.foldLeft(mutable.Map[String, ArrayBuffer[Int]]())((a, b) => {
val key = b._1
val count = b._2
val buf = a.getOrElseUpdate(key, new mutable.ArrayBuffer[Int]())
buf += count
if (buf.size > 3) {
val max3Vals = buf.sorted.takeRight(3)
a(key) = max3Vals
}
a
})
val top3IterPrePartition = temp.toList.flatMap {
case (key, countIters) => countIters.map(count => (key, count))
}
top3IterPrePartition.toIterator
})
.groupByKey()
.flatMap {
case (key, values) => {
val sorted = values.toList.sorted
val top3 = sorted.takeRight(3).reverse
top3.map((key, _))
}
}
result3.foreachPartition(iter => iter.foreach(println))
sc.stop()
思路:
代码实现:
// 构造上下文
val conf = new SparkConf().setMaster("local").setAppName("topn")
val sc = SparkContext.getOrCreate(conf)
// 创建rdd
val path = "datas/groupsort.txt"
val rdd = sc.textFile(path)
// rdd操作得出结果
val rdd2 = rdd.map(_.split(" "))
import scala.collection.mutable
val result4 = rdd2.map(arr => {
val key = arr(0).trim
val count = arr(1).trim.toInt
(key, count)
}).aggregateByKey(mutable.ArrayBuffer[Int]())(
(u, v) => {
u += v
u.sorted.takeRight(3).reverse
},
(u1, u2) => {
u1 ++= u2
u1.sorted.takeRight(3).reverse
}
).flatMap {
case (key, values) => {
values.toList.map((key, _))
}
}
result4.foreachPartition(iter => iter.foreach(println))
sc.stop()
方式1的缺点:
方式2的优缺点:
方式3、方式4:
好了,今天就为大家分享到这里了。咱们下期见!
如果本文对你有帮助的话,欢迎点赞&收藏&分享,这对我继续分享&创作优质文章非常重要。感谢
–END–
扫码上方二维码,加我微信