我正在尝试使流式聚合/ groupBy在附加输出模式下工作,以便能够在流间连接中使用结果流。我正在研究(Py)Spark 2.3.2,并且从Kafka主题中学习。
我的伪代码如下所示,在Zeppelin笔记本中运行
orderStream = spark.readStream().format("kafka").option("startingOffsets", "earliest").....
orderGroupDF = (orderStream
.withWatermark("LAST_MOD", "20 seconds")
.groupBy("ID", window("LAST_MOD", "10 seconds", "5 seconds"))
.agg(
collect_list(struct("attra", "attrb2",...)).alias("orders"),
count("ID").alias("number_of_orders"),
sum("PLACED").alias("number_of_placed_orders"),
min("LAST_MOD").alias("first_order_tsd")
)
)
debug = (orderGroupDF.writeStream
.outputMode("append")
.format("memory").queryName("debug").start()
)
此后,我希望数据会出现在debug
查询上,并且我可以从中选择(在20秒的延迟到达窗口到期后。但是调试查询上没有任何数据出现(我等待几分钟)
当我将输出模式更改为update
时,查询立即生效。
有人暗示我在做什么错吗?
编辑:经过更多的实验后,我可以添加以下内容(但我仍然不理解)。
启动Spark应用程序时,我消耗的主题上有很多旧数据(事件时间戳<<当前时间)。启动后,似乎读取了所有这些消息(例如,日志报告“ numRowsTotal = 6224”中的MicroBatchExecution),但输出未生成任何内容,并且MicroBatchExecution的日志中的eventTime水印停留在纪元(1970-01- 01)。
在将新的消息生成到具有非常接近当前时间的eventTimestamp的输入主题上之后,查询立即立即输出所有“排队”记录,并在查询中增加eventTime水印。
我还可以看到时区似乎有问题。我的Spark程序在CET中运行(当前为UTC + 2)。传入的Kafka消息中的时间戳记采用UTC,例如"LAST__MOD": "2019-05-14 12:39:39.955595000"
。我设置了spark_sess.conf.set("spark.sql.session.timeZone", "UTC")
。尽管如此,在“新”消息被生成到输入主题之后,微批处理报告仍然显示
"eventTime" : {
"avg" : "2019-05-14T10:39:39.955Z",
"max" : "2019-05-14T10:39:39.955Z",
"min" : "2019-05-14T10:39:39.955Z",
"watermark" : "2019-05-14T10:35:25.255Z"
},
因此,eventTime以某种方式与输入消息中的时间相关联,但要2小时。 UTC差异已被细分两次。此外,我看不到水印计算的工作原理。鉴于我将其设置为20秒,所以我希望它比最大事件时间早20秒。但是很明显,这比年龄大14分14秒。我看不到背后的逻辑。
我很困惑...
答案 0 :(得分:0)
这似乎与我使用的Spark版本2.3.2有关,也许更具体地与SPARK-24156有关。我已经升级到Spark 2.4.3,在这里我可以立即获得groupBy的结果(当然,在水印lateThreshold到期之后,但是“在预期的时间范围内。”