Spark结构流(SSS)和Spark Streaming(SS)之间的一个很大区别是SSS可以利用statestore。它可以存储先前批次的聚合结果,并将当前结果应用于先前的结果。因此,它可以从输入流的最开始获得真实的聚合结果。
但是对于一个案例,我们不希望得到与statestore的先前值合并的最终结果。我们只想得到(输出)当前批次的聚合结果。而对于平台和框架的东西,我们无法回滚到SS。
所以我的问题是,在SSS中是否仍然可以获得当前批次的聚合结果,如SS?
以字数统计应用程序为例,它在spark结构流媒体指南中给出: https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
当一批“cat cat
”出现时,我的预期输出为cat|2
。
当下一批“cat
”出现时,我的预期输出为cat|1
答案 0 :(得分:2)
在SSS中仍然可以获得当前的聚合结果 批次,像SS?
实现目标的一种方法是使用mapGroupsWithState
自己控制状态存储,并将其用作一种实际上无法执行任何操作的退化存储。例如:
val spark =
SparkSession.builder().appName("bla").master("local[*]").getOrCreate()
import spark.implicits._
val socketDF = spark.readStream
.format("socket")
.option("host", "127.0.0.1")
.option("port", 9999)
.load()
socketDF
.as[String]
.map { str =>
val Array(key, value) = str.split(';')
(key, value)
}
.groupByKey { case (key, _) => key }
.mapGroupsWithState((str: String,
tuples: Iterator[(String, String)],
value: GroupState[Int]) => {
(str, tuples.size)
})
.writeStream
.outputMode(OutputMode.Update())
.format("console")
.start()
.awaitTermination()
假设我有一个格式为key;value
的值流,这只会使用mapGroupsWithState
作为传递商店,而不是实际累积任何结果。这样,对于每个批次,您将获得一个没有以前聚合数据的干净状态。
答案 1 :(得分:1)
在Spark 2.4中,似乎有更简单的方法可以实现此目标,即使用
foreachBatch
操作,如您在Spark文档中所读。
但是,我使用的是2.3版本的Spark,但尚未解决此问题。
答案 2 :(得分:0)
使用追加输出模式怎么样?
追加模式 - 自上次触发后,只有结果表中附加的新行才会写入外部存储器。这仅适用于预计结果表中现有行不会更改的查询。