Apache spark 每批外部Spark访问数据帧(strutred流)
我想在spark流的foreach批内创建和更新一个数据帧,并在下面的foreach批迭代器外部访问它,这就是我在spark结构化流中尝试做的。 在spark structured streaming中,是否可以从外部访问在每个批次内部创建或更新的数据帧Apache spark 每批外部Spark访问数据帧(strutred流),apache-spark,Apache Spark,我想在spark流的foreach批内创建和更新一个数据帧,并在下面的foreach批迭代器外部访问它,这就是我在spark结构化流中尝试做的。 在spark structured streaming中,是否可以从外部访问在每个批次内部创建或更新的数据帧 // assign a empty data frame var df1: Option[DataFrame] = None: Option[DataFrame] validatedFinalDf.writeStream .foreach
// assign a empty data frame
var df1: Option[DataFrame] = None: Option[DataFrame]
validatedFinalDf.writeStream
.foreachBatch { (batchDF: DataFrame, batchId: Long) =>
println("I am here printing batchDF")
batchDF.withColumn("extra", lit("batch-df")).show()
// un presist the data frame if it has data
if (df1 != None) {
df1.get.unpersist()
}
// assign data to data frame
df1 = Some(batchDF.withColumn("extra", lit("batch-df-dim")))
}.start()
// access data frame outside foreach not working stale data ....
if (df1 != None) {
df1.get.show()
}
spark.streams.awaitAnyTermination()
我甚至无法从外部访问为每个批次在每个批次内部创建的临时表。
甚至在foreach批处理内部更新的数据帧也显示来自foreach批处理外部的过时数据
case class StreamData(
account_id: String,
run_dt: String,
trxn_dt: String,
trxn_amt: String)
import spark.implicits._
implicit val ctx = spark.sqlContext
val streamDataSource = MemoryStream[StreamData]
source.writeStream
.foreachBatch { (batchDf: DataFrame, batchId: Long) =>
val batchDs = batchDf.as[StreamData]
val obj = batchDs
.map(x => StreamData(x.account_id,x.run_dt,x.trxn_dt, x.trxn_amt))
.collect()
streamDataSource.addData(obj)
}
.start()
val datasetStreaming: Dataset[StreamData] = streamDataSource.toDS()
println("This is the streaming dataset:")
datasetStreaming
.writeStream
.format("console")
.outputMode("append")
.start()
spark.streams.awaitAnyTermination()
谢谢
SriforeachBatch
在集合上迭代,如果我没有弄错,则期望执行有效的操作(如写入、打印等)。
但是,在主体内部要做的是将临时结果分配给外部var
因此,存在以下问题:
- 从概念上讲,这是错误的,因为即使它工作得很好,最终也只会得到分配给
var
的last
数据帧
- 我认为您需要
开始
文档中举例说明的操作
DF是不可变的。如果要在使用映射
函数(例如,with column
)或其他转换API时更改数据帧,并返回新的DF
当您对结果感到满意时,只需使用foreach/foreachBatch调用持久化即可一个小技巧,将批处理数据帧转换为在foreach批处理外部访问的内存流
case class StreamData(
account_id: String,
run_dt: String,
trxn_dt: String,
trxn_amt: String)
import spark.implicits._
implicit val ctx = spark.sqlContext
val streamDataSource = MemoryStream[StreamData]
source.writeStream
.foreachBatch { (batchDf: DataFrame, batchId: Long) =>
val batchDs = batchDf.as[StreamData]
val obj = batchDs
.map(x => StreamData(x.account_id,x.run_dt,x.trxn_dt, x.trxn_amt))
.collect()
streamDataSource.addData(obj)
}
.start()
val datasetStreaming: Dataset[StreamData] = streamDataSource.toDS()
println("This is the streaming dataset:")
datasetStreaming
.writeStream
.format("console")
.outputMode("append")
.start()
spark.streams.awaitAnyTermination()
ok找到了一个关于使用内存流的工作,但更多的是寻找没有收集的东西