每个键只保留有限数量的元素

时间:2017-09-12 09:02:55

标签: scala apache-spark

目前我试图找到解决以下问题的方法:

经过一些处理后,我尝试将键值RDD中的值限制为一定数量的键(例如200)。

我的初始解决方案是执行 groupByKey ,将具有相同键的所有元素放入一个分区,然后是 flatMapValues ,其中我将采用前200个可迭代的元素。

虽然这个解决方案对于较小的数据非常适用,但是当我想要处理更大的数据时,它似乎非常低效并且不起作用。

有人知道如何更有效地解决这个问题?

提前致谢!

1 个答案:

答案 0 :(得分:0)

如果数据足够密集(每个键的值的数量>> n,其中n是要保留的记录数),您可以对此进行优化:

  • 从每个分区中获取每个键最多n个元素。
  • 随机播放。
  • 组合,直到每个键有n个元素并忽略其余元素。

在最糟糕的情况下,这将会改变200 *分区数*密钥数。

可以使用combineByKeyaggregateByKey来实施。使用伪代码(您应该使用可变集合来提高性能,如果第一个缓冲区已经有足够的记录,也可以改进mergeCombiners以避免复制):

val rdd: RDD[(K, V)]
rdd.combineByKey(
  x => Vector(x),
  (acc: Vector[V], x: V) => if (acc.length < n) acc :+ x else acc, 
  (acc1: Vector[V], acc2: Vector[V]) => (acc1 ++ acc2) take n
)