Spark:单个流水线scala命令比单独的命令更好?

时间:2013-10-13 01:12:23

标签: scala apache-spark

我正在使用带scala的Spark。我想知道单行命令是否优于单独的命令?有什么好处?它在速度方面是否获得更高的效率?为什么呢?

例如。

var d = data.filter(_(1)==user).map(f => (f(2),f(5).toInt)).groupByKey().map(f=> (f._1,f._2.count(x=>true), f._2.sum))

针对

var a = data.filter(_(1)==user)
var b = a.map(f => (f(2),f(5).toInt))
var c = b.groupByKey()
var d = c.map(f=> (f._1,f._2.count(x=>true), f._2.sum))

2 个答案:

答案 0 :(得分:5)

两个例子之间没有性能差异;链接RDD转换或明确表示中间RDD的决定只是风格问题。 Spark的延迟评估意味着在您调用take()count()之类的RDD操作之前,不会执行任何实际的分布式计算。

在执行期间,Spark将管道尽可能多的转换。对于您的示例,Spark在映射之前不会实现整个过滤数据集:filter()map()转换将一起流水线化并在单个阶段执行。 groupByKey()转换(通常)需要通过网络对数据进行混洗,因此它在单独的阶段执行。只有在filter() d。

的情况下,Spark才会实现cache()的输出

如果要缓存中间RDD并对其执行进一步处理,则可能需要使用第二种样式。例如,如果我想对groupByKey()转换的输出执行多个操作,我会写类似

的内容
val grouped = data.filter(_(1)==user)
                  .map(f => (f(2),f(5).toInt))
                  .groupByKey()
                  .cache()
val mapped = grouped.map(f=> (f._1,f._2.count(x=>true), f._2.sum))
val counted = grouped.count()

答案 1 :(得分:0)

执行方面没有区别,但您可能需要考虑代码的可读性。我会用你的第一个例子,但是像这样:

var d = data.filter(_(1)==user)
.map(f => (f(2),f(5).toInt))
.groupByKey()
.map(f=> (f._1,f._2.count(x=>true), f._2.sum))

实际上,这更像是斯卡拉问题,而不是Spark。尽管如此,正如您可以从Spark的documentation

中显示的字数统计实现中看到的那样
val file = spark.textFile("hdfs://...")
val counts = file.flatMap(line => line.split(" "))
                 .map(word => (word, 1))
                 .reduceByKey(_ + _)
counts.saveAsTextFile("hdfs://...")

你不需要担心这些事情。 Scala语言(通过懒惰等)和Spark的RDD实现处理更高抽象级别的所有内容。

如果您发现性能非常糟糕,那么您应该花时间探索原因。正如Knuth所说,“过早优化是万恶之源。”