【问题标题】:Spark sort by key and then group by to get ordered iterable?Spark按键排序然后分组以获得有序迭代?
【发布时间】:2015-06-29 19:14:00
【问题描述】:

我有一个 Pair RDD (K, V),其密钥包含一个 time 和一个 ID。我想获得(K, Iterable<V>) 形式的 Pair RDD,其中键按 id 分组,可迭代按时间排序。

我目前正在使用sortByKey().groupByKey(),我的测试似乎证明它有效,但我了解到情况可能并非总是如此,正如本问题中讨论的那样,答案各不相同 (Does groupByKey in Spark preserve the original order?)。

正确与否?

谢谢!

【问题讨论】:

  • 如果您需要更好的答案,请悬赏另一个问题。这是您提到的问题的副本。

标签: sorting apache-spark


【解决方案1】:

The answer from Matei,我认为这个话题的权威,很清楚:

实际上并不能保证顺序,只有在每个键中都有哪些键 划分。 Reducers 可以任意从 map 任务中获取数据 顺序,取决于哪些是最先可用的。如果你想要一个 具体顺序,你应该对每个分区进行排序。你可能在这里 得到它是因为每个分区最终只有一个元素,并且 collect() 确实按顺序返回分区。

在这种情况下,更好的选择是将排序应用于每个键的结果集合:

rdd.groupByKey().mapValues(_.sorted)

【讨论】:

  • 对,取决于数据集(重复键的数量),但最好在较少的“行”上进行排序,在它们已经被分组折叠之后。
  • @MarkoBonaci 这就是这里发生的事情。在groupByKey 之后,对结果分组进行排序以满足问题中的要求。我不确定评论是关于什么的。你能澄清一下吗?
  • 我只是在确认你的最后一句话,并试图解释为什么这样更好。我们很酷:)
  • @maasg 它是在 spark 文档中编写的,以尽可能避免 groupByKey。然而,在我看来,在一个组内排序这似乎是唯一的选择。有没有其他方法可以达到同样的效果?
【解决方案2】:

Spark Programming Guide 提供了三种选择,如果人们希望在 shuffle 之后获得可预测的有序数据:

  • mapPartitions 使用例如.sorted 对每个分区进行排序
  • repartitionAndSortWithinPartitions 有效地对分区进行排序,同时重新分区
  • sortBy 做一个全局排序的 RDD

正如Spark API 中所写,repartitionAndSortWithinPartitions 比调用 repartition 然后在每个分区内排序更有效,因为它可以将排序下推到 shuffle 机器中。

但是,排序是通过仅查看元组 (K, V) 的键 K 来计算的。诀窍是将所有相关信息放在元组的第一个元素中,例如((K, V), null),定义自定义分区器和自定义排序。 This article 很好地描述了这项技术。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 2023-03-30
    • 2016-01-15
    相关资源
    最近更新 更多