在foreachPartition中执行Mysql查询spark运行缓慢

时间:2018-06-08 21:59:39

标签: mysql apache-spark

我想在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。我很好奇是什么原因导致这个查询运行缓慢。

1 个答案:

答案 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