Spark结构化流式传输foreachpartition /连接池问题

时间:2018-05-17 20:37:33

标签: apache-spark spark-structured-streaming

我正在使用结构化流媒体从Kafka读取数据,我需要保存 关于InfluxDB的数据。在常规的基于Dstreams的方法中,我做到了这一点 如下:

val messages:DStream[(String, String)] =  kafkaStream.map(record => 
(record.topic, record.value)) 
messages.foreachRDD { rdd => 
  rdd.foreachPartition { partitionOfRecords => 
    val influxService = new InfluxService() 
    val connection = influxService.createInfluxDBConnectionWithParams( 
        host, 
        port, 
        username, 
        password, 
        database 
        ) 
    partitionOfRecords.foreach(record => { 
      ABCService.handleData(connection, record._1, record._2) 
    } 
    ) 
  } 
} 
ssc.start() 
logger.info("Started Spark-Kafka streaming session") 
ssc.awaitTermination() 

注意

我在foreachpartition内创建连接对象。我该怎么做呢 在结构化流媒体?

我尝试了连接池方法(我在哪里 在主节点上创建连接池并将其传递给工作节点 ) 这里 Spark connection pooling - Is this the right approach
并且worker无法获取连接池对象。一切都很明显 我在这里失踪了?

1 个答案:

答案 0 :(得分:1)

结构化流式传输具有完全不同的设计,基于旧RDD的模式在那里并不适用。

相反,您应该实现自己的ForeachWriter 。它需要三种方法:

  • open

      

    abstract def open(partitionId: Long, version: Long): Boolean   在执行程序中开始处理新数据的一个分区时调用。

    这是初始化连接对象的位置。一般来说,它不应该依赖于通过关闭传递的对象(你在第二个问题中犯的错误)。

    如果要限制连接数,可以使用单例对象,只要所有组件都是线程安全的。

  • process

    abstract def process(value: T): Unit
    
         

    被调用以处理执行方的数据。

    这相当于foreach

  • close

      

    abstract def close(errorOrNull: Throwable): Unit

         

    在执行程序端停止处理新数据的一个分区时调用。

    这是您可以关闭连接并减少其他临时对象的地方。