附加模式下的水印聚合查询的空输出

时间:2017-06-07 04:45:16

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

我使用Spark 2.2.0-rc1。

我有一张Kafka topic我正在查询带有1 minute水印的正在运行的水印聚合,并consoleappend发送import org.apache.spark.sql.types._ val schema = StructType(StructField("time", TimestampType) :: Nil) val q = spark. readStream. format("kafka"). option("kafka.bootstrap.servers", "localhost:9092"). option("startingOffsets", "earliest"). option("subscribe", "topic"). load. select(from_json(col("value").cast("string"), schema).as("value")) select("value.*"). withWatermark("time", "1 minute"). groupBy("time"). count. writeStream. outputMode("append"). format("console"). start 输出模式。

topic

我正在推动Kafka {"time":"2017-06-07 10:01:00.000"} {"time":"2017-06-07 10:02:00.000"} {"time":"2017-06-07 10:03:00.000"} {"time":"2017-06-07 10:04:00.000"} {"time":"2017-06-07 10:05:00.000"} 中的数据:

scala> -------------------------------------------
Batch: 0
-------------------------------------------
+----+-----+                                                                    
|time|count|
+----+-----+
+----+-----+

-------------------------------------------
Batch: 1
-------------------------------------------
+----+-----+                                                                    
|time|count|
+----+-----+
+----+-----+

-------------------------------------------
Batch: 2
-------------------------------------------
+----+-----+                                                                    
|time|count|
+----+-----+
+----+-----+

-------------------------------------------
Batch: 3
-------------------------------------------
+----+-----+                                                                    
|time|count|
+----+-----+
+----+-----+

-------------------------------------------
Batch: 4
-------------------------------------------
+----+-----+                                                                    
|time|count|
+----+-----+
+----+-----+

我得到以下输出:

still need merge

这是预期的行为吗?

2 个答案:

答案 0 :(得分:8)

向Kafka推送更多数据应该会触发Spark输出内容。目前的行为完全是因为内部实施。

当您推送一些数据时,StreamingQuery将生成一个要运行的批处理。当该批次完成时,它将记住该批次中的最大事件时间。然后在下一批, 因为您使用append模式,StreamingQuery将使用最大事件时间和水印来从StateStore中逐出旧值并输出它。因此,您需要确保至少生成两个批次才能看到输出。

答案 1 :(得分:4)

这是我最好的猜测:

追加模式仅在水印通过后输出数据(例如,在这种情况下1分钟后)。您没有设置触发器(例如.trigger(Trigger.ProcessingTime("10 seconds")),因此默认情况下它会尽快输出批次。因此,对于第一分钟,所有批次都应为空,一分钟后的第一批应包含一些内容。

另一种可能性是您使用的是groupBy("time")而不是groupBy(window("time", "[window duration]"))。我相信水印意味着与时间窗口或mapGroupsWithState一起使用,所以在这种情况下,我不是交互的工作方式。