按键分组火花组多个rdd项目

时间:2016-04-06 09:32:27

标签: scala apache-spark

我有rdd项目,如:

(3922774869,10,1)
(3922774869,11,1)
(3922774869,12,2)
(3922774869,13,2)
(1779744180,10,1)
(1779744180,11,1)
(3922774869,14,3)
(3922774869,15,2)
(1779744180,16,1)
(3922774869,12,1)
(3922774869,13,1)
(1779744180,14,1)
(1779744180,15,1)
(1779744180,16,1)
(3922774869,14,2)
(3922774869,15,1)
(1779744180,16,1)
(1779744180,17,1)
(3922774869,16,4)
...

代表(id, age, count),我想将这些行分组以生成一个数据集,其中每一行代表每个id的年龄分布,如下所示((id, age)为uniq):

(1779744180, (10,1), (11,1), (12,2), (13,2) ...)
(3922774869, (10,1), (11,1), (12,3), (13,4) ...)

(id, (age, count), (age, count) ...)

有人可以给我一些线索吗?

2 个答案:

答案 0 :(得分:8)

您可以先减少两个字段,然后使用groupBy:

rdd
  .map { case (id, age, count) => ((id, age), count) }.reduceByKey(_ + _)
  .map { case ((id, age), count) => (id, (age, count)) }.groupByKey()

返回RDD[(Long, Iterable[(Int, Int)])],对于上面的输入,它将包含这两个记录:

(1779744180,CompactBuffer((16,3), (15,1), (14,1), (11,1), (10,1), (17,1)))
(3922774869,CompactBuffer((11,1), (12,3), (16,4), (13,3), (15,3), (10,1), (14,5)))

答案 1 :(得分:3)

正如Tzach Zohar已经建议的那样,你可以首先重塑你的RDD以适应Key / Value RDD。如果你有一个非常大的数据集,我建议你不要使用groupByKey,以减少改组,虽然它看起来非常简单。 例如,将此解决方案基于已发布的解决方案:

import scala.collection.mutable

val rddById = rdd.map { case (id, age, count) => ((id, age), count) }.reduceByKey(_ + _)
val initialSet = mutable.HashSet.empty[(Int, Int)]
val addToSet = (s: mutable.HashSet[(Int, Int)], v: (Int, Int)) => s += v
val mergePartitionSets = (p1: mutable.HashSet[(Int, Int)], p2: mutable.HashSet[(Int, Int)]) => p1 ++= p2
val uniqueByKey = rddById.aggregateByKey(initialSet)(addToSet, mergePartitionSets)

这将导致

uniqueByKey: org.apache.spark.rdd.RDD[(AnyVal, scala.collection.mutable.HashSet[(Int, Int)])]

您将能够将值打印为:

scala> uniqueByKey.foreach(println)
(1779744180,Set((15,1), (16,3)))
(1779744180,Set((14,1), (11,1), (10,1), (17,1)))
(3922774869,Set((12,3), (11,1), (10,1), (14,5), (16,4), (15,3), (13,3)))

洗牌可能是一个很大的瓶颈。拥有许多大的HashSet(根据您的数据集)也可能是个问题。但是,你更有可能拥有大量内存(例如,64GB内存?)而不是网络延迟(以及随机出现的所有问题),这会导致分布式计算机上的读/写速度更快。

要详细了解aggregateByKey,请查看此blog post