我正在使用Spark结构化流,并处理来自Kafka的消息。 有时,结果表如下所示,其中数据集中的每一行都有一个Spark SQL查询。
+----+--------------------+
|code| triggerSql|
+----+--------------------+
| US|SELECT * FROM def...|
| UK|SELECT * FROM def...|
+----+--------------------+
我需要执行每个查询并处理结果。但是,结构化流不允许将这些SQL收集到驱动程序端,并且我们不能在任何转换内打开新的SparkSession。
val query = df3.writeStream.foreach(new ForeachWriter[Row] {
override def open(partitionId: Long, epochId: Long): Boolean = {
//..
}
override def process(value: Row): Unit = {
val triggerSqlString = value.getAs[String]("triggerSql")
val code = value.getAs[String]("value")
println("Code="+code+"; TriggerSQL="+triggerSqlString)
//TODO
}
override def close(errorOrNull: Throwable): Unit = {
// println("===> Closing..")
}
}).trigger(Trigger.ProcessingTime("5 seconds"))
.start()
有没有更好的替代方法可以在spark中动态执行这些SQL。
答案 0 :(得分:0)
tl; dr 使用DataStreamWriter.foreachBatch操作。
以下示例显示了如何从批处理数据集中执行SQL查询:
def sqlExecution(ds: Dataset[String], batchId: Long): Unit = {
ds.as[String].collect.foreach { s => sql(s).show }
}
spark
.readStream
.textFile("sqls")
.writeStream
.foreachBatch(sqlExecution)
.start