Apache spark 使用PartitionBy按键拆分和高效计算RDD组
我已经实现了一个解决方案,通过键对组Apache spark 使用PartitionBy按键拆分和高效计算RDD组,apache-spark,rdd,Apache Spark,Rdd,我已经实现了一个解决方案,通过键对组RDD[K,V],并使用partitionBy和Partitioner根据每个组(K,RDD[V])计算数据。然而,我不确定它是否真的有效,我想听听你的观点 下面是一个示例案例:根据[K:Int,V:Int]列表,计算K每组的Vs平均值,知道它应该分布,并且V值可能非常大。这将使: List[K, V] => (K, mean(V)) 简单分区器类: class MyPartitioner(maxKey: Int) extends Partitione
RDD[K,V]
,并使用partitionBy
和Partitioner
根据每个组(K,RDD[V])
计算数据。然而,我不确定它是否真的有效,我想听听你的观点
下面是一个示例案例:根据[K:Int,V:Int]
列表,计算K
每组的V
s平均值,知道它应该分布,并且V
值可能非常大。这将使:
List[K, V] => (K, mean(V))
简单分区器类:
class MyPartitioner(maxKey: Int) extends Partitioner {
def numPartitions = maxKey
def getPartition(key: Any): Int = key match {
case i: Int if i < maxKey => i
}
}
输出为:
1->13,2->4,3->7
我的问题是:
partitionBy
时,实际会发生什么情况?(对不起,我没有找到足够的规格)mean()的输入中,我需要一个RDD
)
关于您的代码不应该工作。无法将
SparkContext
对象传递给执行器。(它不是可序列化的
)我也不明白你为什么需要这样做
要计算平均值,您需要计算总和和计数,并取它们的比率。默认的分区器可以正常工作
def meanByKey(rdd: RDD[(Int, Int)]): RDD[(Int, Double)] = {
case class SumCount(sum: Double, count: Double)
val sumCounts = rdd.aggregateByKey(SumCount(0.0, 0.0))(
(sc, v) => SumCount(sc.sum + v, sc.count + 1.0),
(sc1, sc2) => SumCount(sc1.sum + sc2.sum, sc1.count + sc2.count))
sumCounts.map(sc => sc.sum / sc.count)
}
这是一个有效的单程计算,具有很好的通用性。感谢您的回答,当然它不可能工作,我没有所有的火花编码技巧反射,我已经被我的本地jvm宠坏了。然而,实际上我不需要计算平均值,而是一个复杂的ml方法,我需要一个RDD[向量]。如何从唯一的RDD[Int,Int]获取(key,RDD[Vector])列表?我没有找到解决方案。我想这是一个类似的主题:我不确定如何从
Int
s生成Vector
s。但是,如果您希望每个键获得一个RDD,则需要拆分原始RDD,这将在链接的答案中讨论。如果它不能给你答案,我建议你再问一个问题,也许要对你想做的事情有一个清晰、高层次的解释。
def meanByKey(rdd: RDD[(Int, Int)]): RDD[(Int, Double)] = {
case class SumCount(sum: Double, count: Double)
val sumCounts = rdd.aggregateByKey(SumCount(0.0, 0.0))(
(sc, v) => SumCount(sc.sum + v, sc.count + 1.0),
(sc1, sc2) => SumCount(sc1.sum + sc2.sum, sc1.count + sc2.count))
sumCounts.map(sc => sc.sum / sc.count)
}