例如,我们有一个镶木地板文件,过去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操作呢?
答案 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,它是分布式的。