带有groupBy的DataFrame与带有reduceByKey的RDD

时间:2017-08-28 07:32:36

标签: scala apache-spark apache-spark-sql

我有一个csv文件:(customerId,orderId,spend)。我使用两种方法计算每个客户的总支出:

方法1 :使用DataFrame和groupBy

val df = ss.read
.option("header", false)
.option("inferSchema", true)
.csv("data.csv")

df
.groupBy("_c0")
.sum("_c2")
.collect()

方法2 :使用RDD和reduceByKey

sc
.textFile("data.csv")
.map(parseLine)
.reduceByKey(_ + _)
.collect()

private def parseLine(line: String) = {
  val fields = line.split(",")
  (fields(0).toInt, fields(2).toFloat)
}

两种方法的结果是相同的。然而,方法2总是比方法1更快(2x)。

第一个问题:这是因为方法1正在使用groupBy吗?如果是这样,当我在笔记本电脑上运行时,怎么会发生这种情况。即只有1个节点,即没有洗牌成本?

这是我的火花会话配置

.master("local[*]") 

第二个问题:如何在保留良好性能(如方法2)的同时修改方法1以使用DataFrame?

谢谢!

1 个答案:

答案 0 :(得分:1)

您的第一个代码扫描数据两次:

  • 一次到inferchema
  • 一次执行计数。

如果没有任何进一步的信息,我会将执行速度降低到这个事实。还有其他差异,例如计算执行计划的成本。

特定内存配置(包括堆外内存的大小)可能会进一步影响性能。

  

如何修改方法1以使用DataFrame,同时保留良好的性能,如方法2?

read方法提供架构参数。

  

当我在笔记本电脑上运行时,怎么会发生这种情况。即只有1个节点,即没有洗牌成本?

由于本地通信,本地计算机上的随机播放成本可能会降低,但它仍然是一个完整的混乱,包括磁盘IO,而且它仍然很昂贵。

  

这是因为方法1正在使用groupBy

不。groupBy与此无关。 Dataset.groupBy不是RDD.groupBy(Key)