我正在使用结构化流媒体从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无法获取连接池对象。一切都很明显
我在这里失踪了?
答案 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
在执行程序端停止处理新数据的一个分区时调用。
这是您可以关闭连接并减少其他临时对象的地方。