如何用scala并行化spark中的for循环?

时间:2016-05-03 13:32:20

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

例如,我们有一个镶木地板文件,过去3年有2000个股票代码的收盘价,我们想计算每个符号的5天移动平均线。

所以我创建了一个spark SQLContext然后

val marketData = sqlcontext.sql("select DATE, SYMBOL, PRICE from stockdata order by DATE").cache()

获取符号列表

val symbols = marketData.select("SYMBOL").distinct().collect()

这是for循环:

for (symbol <- symbols) {
  marketData.filter(symbol).rdd.sliding(5).map(...calculating the avg...).save()
}

显然,在spark上执行for循环很慢,并且每个小结果save()也会减慢进程(我尝试在for循环外定义var result并将所有输出联合到同时进行IO操作,但是我遇到了stackoverflow异常),那么如何并行化for循环并优化IO操作呢?

2 个答案:

答案 0 :(得分:3)

您编写的程序在驱动程序(“master”)spark节点中运行。如果您在并行结构(RDD)上运行,则此程序中的表达式只能并行化。

试试这个:

marketdata.rdd.map(symbolize).reduceByKey{ case (symbol, days) => days.sliding(5).map(makeAvg)  }.foreach{ case (symbol,averages) => averages.save() }

其中symbolize占用一行符号x天并返回一个元组(符号,日期)。

答案 1 :(得分:3)

对于答案的第一部分,我不同意Carlos。该程序不在驱动程序中运行(&#34; master&#34;)。

循环确实按顺序运行,但对于每个符号执行:

marketData.filter(symbol).rdd.sliding(5).map(...calculating the avg...).save()

是并行完成的,因为markedData是一个Spark DataFrame,它是分布式的。