具有foreachRDD Spark流的数据库连接

时间:2018-07-10 13:40:13

标签: scala apache-spark neo4j spark-streaming

我在流传输数据时创建并传递到数据库的连接。每次从文件读取数据并创建Neo4j会话都会增加性能开销。如何更改现有代码以提高应用程序的性能?我应该将foreachRDD更改为foreachPartition以便为连接创建单独的对象吗?

这是我的流式传输代码:

val wordsArrays: DStream[Array[String]] = values.map(t => t.split(", "))

wordsArrays.foreachRDD(rdd => {

  rdd.flatMap(
  data => {
    val recommendations = execNeo4jSearchQuery(neo4jConfigs.getNeo4jConfig(args(1)), data)
    val calendarTime = Calendar.getInstance.getTime
    val recommendationsMap = convertDataToMap(recommendations, calendarTime)
    recommendationsMap

  }).saveToEs("rdd-timed/output")
 }
)

2 个答案:

答案 0 :(得分:2)

foreachPartiotion使您可以按分区而不是按地图迭代创建对象, 当您需要为每个分区创建单个连接时,它很有用。

但是在您的情况下,似乎您创建的所有对象都取决于地图的输入值或当前时间。所以我看不出它将对您有什么帮助。

除非您在每次execNeo4jSearchQuery的运行中都创建一个连接,否则我看不到它如何为您提供帮助,但是,如果您确实创建了一个连接,则对不依赖于数据的函数的每次调用都将有助于改善代码。 (但是瓶颈不存在,所以您不会看到很大的进步)。

答案 1 :(得分:1)

最好使用具有mapPartitions的数据库连接,然后将具有更新分区的rdd保存到ElasticSearch:

 wordsArrays.foreachRDD(rdd => {

      rdd.mapPartitions { partition => {
            val neo4jConfig = neo4jConfigurations.getNeo4jConfig(args(1))

            val result = partition.map( data => {

              val recommendations = execNeo4jSearchQuery(neo4jConfig, data)
              val calendarTime = Calendar.getInstance.getTime
              convertDataToMap(recommendations, calendarTime)

          }).toList.flatten
          result.iterator
        }
      }.saveToEs("rdd-timed/output")
    })