使用 Scala 根据 RDD 中的多个键列对值进行分组的最快方法是啥? [复制]

Posted

技术标签:

【中文标题】使用 Scala 根据 RDD 中的多个键列对值进行分组的最快方法是啥? [复制]【英文标题】:What is the fastest way to group values based on multiple key columns in RDD using Scala? [duplicate]使用 Scala 根据 RDD 中的多个键列对值进行分组的最快方法是什么? [复制] 【发布时间】:2017-10-02 17:45:57 【问题描述】:

我的数据是一个包含超过 200 万行员工记录的文件。每行有15个员工特征字段,包括姓名、出生日期、ssn等。示例:

ID|name|DOB|address|SSN|...
1|James Bond|10/01/1990|1000 Stanford Ave|123456789|...
2|Jason Bourne|05/17/1987|2000 Yale Rd|987654321|...
3|James Bond|10/01/1990|5000 Berkeley Dr|123456789|...

我需要按多列对数据进行分组,并使用相同的键聚合员工的 ID(第一列)。键列的数量和名称作为参数传递给函数。

例如,如果关键列包括“姓名、出生日期、SSN”,则数据将被分组为

(James Bond, 10/01/1990, 123456789), List(1,3)
(Jason Bourne, 05/17/1987, 987654321), List(2)

最后的输出是

List(1,3)
List(2)

我是 Scala 和 Spark 的新手。我解决这个问题的方法是:将数据读取为RDD,并根据我对***的研究尝试使用groupBy、reduceByKey和foldByKey来实现该功能。其中,我发现 groupBy 最慢,而 foldByKey 最快。我使用 foldByKey 的实现是:

val buckets = data.map(row => (idx.map(i => row(i)) -> (row(0) :: Nil)))
                  .foldByKey(List[String]())((acc, e) => acc ::: e).values

我的问题是:在 RDD 上使用 foldByKey 是否有比我更快的实现?

更新:我已阅读 *** 上的帖子并了解 groupByKey 在大型数据集上可能非常慢。这就是为什么我确实避免使用 groupByKey 并最终选择了 foldByKey。然而,这不是我问的问题。我正在寻找更快的实现,或者在固定硬件设置的处理时间方面的最佳实现。 (现在处理 200 万条记录需要大约 15 分钟。)有人告诉我,将 RDD 转换为 DataFrame 并调用 groupBy 可以更快。

【问题讨论】:

【参考方案1】:

以下是其中的一些详细信息,以了解它们的工作原理。

groupByKey 运行缓慢,因为所有键值对都被打乱了。这是通过网络传输的大量不必要的数据。

reduceByKey 在大型数据集上效果更好。这是因为 Spark 知道它可以在对数据进行混洗之前将输出与每个分区上的公共键组合起来。

combineByKey 可用于组合元素但返回类型与输入值类型不同时。

foldByKey 使用关联函数和中性“零值”合并每个键的值。

所以避免groupbyKey。希望这会有所帮助。

干杯!

【讨论】:

以上是关于使用 Scala 根据 RDD 中的多个键列对值进行分组的最快方法是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Pandas pivot_table,按列对值进行排序

Spark Scala 按唯一键对值求和

PySpark - 按第二列对 RDD 进行排序

使用 Scala 清理 RDD 中的开括号和闭括号

Scala - 基于 Spark 中的键合并两个 RDD

rdd.mapPartitions 从 Spark Scala 中的 udf 返回布尔值