2

我有一个RDD具有以下结构的:

val rdd = RDD[ (category: String, product: String, score: Double) ]

我的目标是group基于类别的数据,然后对于每个类别sort的得分为Tuple 2 (product, score). 至于现在我的代码是:

val result = rdd.groupByKey.mapValues(v => v.toList.sortBy(-_._2))

事实证明,对于我拥有的数据来说,这是非常昂贵的操作。我希望使用替代方法来提高性能。

4

2 回答 2

3

在不知道您的数据集的情况下很难回答,但文档中有一些线索:groupByKey性能:

注意:此操作可能非常昂贵。如果您正在分组以便对每个键执行聚合(例如求和或平均),则使用 PairRDDFunctions.aggregateByKey 或 PairRDDFunctions.reduceByKey 将提供更好的性能。

所以这取决于你打算对排序列表做什么。如果您需要每个列表的全部内容,那么可能很难改进groupByKey. 如果您正在执行某种聚合,那么上面的替代操作 ( aggregateByKey, reduceByKey) 可能会更好。

根据列表的大小,在排序之前使用替代集合(例如可变数组)可能更有效。

编辑:如果您的类别数量相对较少,您可以尝试重复过滤原始 RDD,并对每个过滤后的 RDD 进行排序。尽管总体上完成了类似的工作量,但在任何给定时刻它可能会使用更少的内存。

编辑 2:如果内存不足是一个问题,您可以将您的类别和产品表示为整数 ID 而不是字符串,并且稍后再查找名称。这样,您的主要 RDD 可能会小得多。

于 2016-04-29T15:39:29.790 回答
0

您的 RDD 在类别上是否公平分布?根据您的偏斜因素,您可能会遇到问题。如果您没有太多键值,请尝试这样的操作:

val rdd: RDD[(String, String, Double)] = sc.parallelize(Seq(("someCategory","a",1.0),("someCategory","b",3.0),("someCategory2","c",4.0)))

rdd.keyBy(_._1).countByKey().foreach(println)
于 2016-04-29T15:45:37.650 回答