Spark结构化流中对同一数据帧/数据集的多个操作/聚合

时间:2019-03-19 08:15:25

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

我使用Spark 2.3.2。

我正在从Kafka接收数据。我必须对同一数据进行多次汇总。然后,所有聚合结果都将转到相同的数据库(列或表可能会更改)。例如:

val kafkaSource = spark.readStream.option("kafka") ...
val agg1 = kafkaSource.groupBy().agg ...
val agg2 = kafkaSource.groupBy().mapgroupswithstate() ...
val agg3 = kafkaSource.groupBy().mapgroupswithstate() ...

但是当我尝试为每个聚合结果调用writeStream时:

aggr1.writeStream().foreach().start()
aggr2.writeStream().foreach().start()
aggr3.writeStream().foreach().start()

Spark在每个writeStream中独立接收数据。这样有效吗?

我可以使用一个writeStream进行多个聚合吗?如果可能的话,这种方式有效吗?

2 个答案:

答案 0 :(得分:1)

每个“ writestream”操作都会产生一个新的流查询。每个流查询都将从源中读取并执行整个查询计划。与DStream不同,没有可用的缓存/持久选项。

在spark 2.4中,引入了新的API“ forEachBatch”以更有效地解决此类情况。

答案 1 :(得分:0)

可以使用缓存来避免多次读取:

kafkaSource.writeStream.foreachBatch((df, id) => {
  df.persist()
  val agg1 = df.groupBy().agg ...
  val agg2 = df.groupBy().mapgroupswithstate() ...
  val agg3 = df.groupBy().mapgroupswithstate() ...
  df.unpersist()
}).start()