【问题标题】:Only keep a limited amount of elements per key每个键只保留有限数量的元素
【发布时间】:2017-09-12 17:40:16
【问题描述】:

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

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

我最初的解决方案是做一个 groupByKey,将具有相同键的所有元素放入一个分区,然后是一个 flatMapValues,我将只取前 200 个可迭代的元素。

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

有人知道如何更有效地实现这一目标?

提前致谢!

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    如果数据足够密集(每个键的值数为 >> 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
    )
    

    【讨论】:

      猜你喜欢
      • 2016-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      • 2012-08-02
      相关资源
      最近更新 更多