我使用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进行多个聚合吗?如果可能的话,这种方式有效吗?
答案 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()