在传入事件之前的20秒内实施基于滑动窗口的聚合的正确方法是什么?时间戳' SPARK v.2.2.0中的值?
案例非常简单 - 每次活动到来时,我都要检查在之前的$ timestamp - 20秒内是否还有其他此类事件。为了简单起见 - 我可以忽略迟到的事件(不需要水印)。
目前,通过定义类似于window($"timestamp", "20 seconds")
的窗口,我获得具有固定开始/结束时间戳的结果(从每分钟开始每20秒:00秒)。基本上我需要的是由以下各个时期定义的聚合:
请看一下我正在使用的简单示例:
使用linux netcat工具通过发出命令生成给定套接字号上的单词:
nc -lk -p 9999
将以下scala脚本粘贴到spark-shell
:
val lines = spark.readStream.
format("socket").
option("host", "localhost").
option("port", 9999).
option("includeTimestamp", true).
load()
import org.apache.spark.sql.functions._
val windowedCounts = lines.
groupBy(
window($"timestamp", "20 seconds"),
$"value").
agg(count($"value") as "count", last($"timestamp") as "last_ts", first($"timestamp") as "first_ts").
select($"window.start", $"window.end", $"last_ts", $"first_ts", $"value", $"count")
val query = windowedCounts.writeStream.
outputMode("complete").
format("console").
option("truncate", false).
start()
通过生成随机的单词'在您的netcat窗口中,您会注意到类似于以下内容的内容:
+-------------------+-------------------+-------------------+-------------------+-----+-----+
|start |end |last_ts |first_ts |value|count|
+-------------------+-------------------+-------------------+-------------------+-----+-----+
|2017-10-11 11:21:00|2017-10-11 11:21:20|2017-10-11 11:21:02|2017-10-11 11:21:17|word |7 |
|2017-10-11 11:21:20|2017-10-11 11:21:40|2017-10-11 11:21:21|2017-10-11 11:21:21|word |1 |
+-------------------+-------------------+-------------------+-------------------+-----+-----+
'字'在11:21:21生成的是一个新的时间窗口,因此计算了#39;等于一个。但是我希望它是8,因为在过去的20秒内有8个事件(第一个时间戳为11:21:02)。
如何在Spark Structured Streaming v.2.2.0中基于事件时间实现滑动窗口?任何建议都高度赞赏。