Spark结构化的流式传输组无法在附加模式下工作(可在更新中工作)

时间:2019-05-13 14:00:45

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

我正在尝试使流式聚合/ 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秒。我看不到背后的逻辑。

我很困惑...

1 个答案:

答案 0 :(得分:0)

这似乎与我使用的Spark版本2.3.2有关,也许更具体地与SPARK-24156有关。我已经升级到Spark 2.4.3,在这里我可以立即获得groupBy的结果(当然,在水印lateThreshold到期之后,但是“在预期的时间范围内。”