这个问题在这里已有答案:
我的数据是一个包含超过200万行员工记录的文件 . 每行有15个员工功能字段,包括名称,DOB,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(第一列) . 键列的数量和名称作为参数传递给函数 .
例如,如果键列包含“name,DOB,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来实现基于我对StackOverflow的研究的功能 . 其中,我发现groupBy是最慢的,而foldByKey是最快的 . 我在 foldByKey 的实现是:
val buckets = data.map(row => (idx.map(i => row(i)) -> (row(0) :: Nil)))
.foldByKey(List[String]())((acc, e) => acc ::: e).values
My question is: Is there faster implementation than mine using foldByKey on RDD?
更新:我已阅读StackOverflow上的帖子,并了解groupByKey在大型数据集上可能会非常慢 . 这就是为什么我确实避免了groupByKey并最终得到了foldByKey . 但是,这不是我问的问题 . 我正在寻找更快的实现,或者在固定硬件设置的处理时间方面的最佳实现 . (处理200万条记录现在需要大约15分钟 . )我被告知将RDD转换为DataFrame并调用groupBy可以更快 .
1 回答
以下是每个细节的一些细节,以了解它们的工作原理 .
groupByKey 运行缓慢,因为所有的键值对都是混乱的 . 这是通过网络传输的大量不确定数据 .
reduceByKey 在大型数据集上工作得更好 . 这是因为Spark知道它可以在混洗数据之前将输出与每个分区上的公共密钥组合在一起 .
组合元素时可以使用 combineByKey ,但返回类型与输入值类型不同 .
foldByKey 使用关联函数和中性"zero value"合并每个键的值 .
所以避免 groupbyKey . 希望这会有所帮助 .
干杯!