使用Spark结构化流媒体时,如何获取当前批处理的聚合结果,如Spark Streaming?

时间:2018-01-23 15:12:02

标签: apache-spark spark-streaming spark-structured-streaming

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

3 个答案:

答案 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)

使用追加输出模式怎么样?

  

追加模式 - 自上次触发后,只有结果表中附加的新行才会写入外部存储器。这仅适用于预计结果表中现有行不会更改的查询。