我想在spark中的foreachparition中执行mysql查询,并最终将所有查询结果传递给数据帧。 它看起来像:
var rowAccumulator: RowAccumulator = new RowAccumulator
foreachPartition((p) => {
val result = MysqlService.getData(query, p)
rowAccumulator.add(result)
})
然后将rowAccumulator
转换为数据框。
然而,它加速运行缓慢。例如,第一个查询需要130毫秒,第二个查询需要150000毫秒。我注意到在MysqlService中,我每次都创建数据库会话,这可能是不正确的。有没有更好的方法呢?
更新: MysqlService用于不同的地方,我们希望使代码易于维护。如果它不能很好地执行,我们可以应用不同的方式来执行查询,例如使用spark jdbc。我很好奇是什么原因导致这个查询运行缓慢。
答案 0 :(得分:0)
Spark累加器不是为处理大量数据而设计的。主要用于使用在常量内存中运行的方法(如计数器)来收集辅助统计信息。
使用像这样的累加器是collect
的效率较低的变体(不推荐使用collect
),如果你
将rowAccumulator转换为数据框。
由于你使用MySQL数据库,你应该首先看看Spark的JDBC connector:
spark.read.jdbc(...)
并且只有在您有特殊要求时才使用自定义代码。如果您确实直接使用map
rdd.foreachPartition((p) => {
MysqlService.getData(query, p)
}).map(x => anyRequiredTransformation(x)).toDF