- 基本概念
事件时间顾名思义就是嵌入在数据事件内部的时间。对很多应用程序来说,可能希望按照事件时间进行处理。例如,你想统计lot设备每分钟产生事件的个数,那么你肯定希望用数据产生的时间,而不是spark接收到数据的时间。可以做如下类比,每个设备中产生的数据就是表中的一行,然后事件时间就是该行里的一个列值。这时候就可以使用基于窗口的聚合函数基于事件时间列进行分组聚合,每个时间窗口就是一个组,每行可以属于多个窗口/组。因此该事件时间窗口聚合查询在静态数据集或者流数据集上定义使用就很一致了,让我们使用起来更简单。
另外,该模型会很自然的处理那些基于事件时间滞后的数据。由于spark 会去更新结果表,那么spark 就能够完全控制当有滞后的数据到达时处理数据然后更新结果表,同时也可以清除旧的聚合状态来限制中间状态的大小。从spark 2.1开始支持了watermark机制,允许用户指定一个数据之后的最大时间阈值,然后允许引擎根据该阈值清理中间状态。
2. update sink
数据传输过程中由于网络故障等会有概率延迟,那么这种情况的处理structured streaming和flink类似,都有watermark的概念,当然这个概念只会在事件时间上生效。例如,假如一个word是在12:04产生,但是在12:11被接收到。应用应该使用的时间是12:04而不是12:11去更新12:00-12:10这个窗口。这在我们基于窗口的分组中自然处理的 – structured streaming可以长时间维持部分聚合的中间状态,以便后期数据可以正确更新旧窗口的聚合。如下所示。
但是,为了使查询持续运行,系统必须限制其积累在内存中的中间状态数据量。这意味着系统需要知道何时可以从内存状态中删除旧聚合状态,因为应用程序不会再为该聚合操作接收较晚的数据。为了实现这一点,在Spark 2.1中,引入了watermark概念,这使得引擎可以自动跟踪数据中的当前事件时间,并尝试相应地清除旧状态。可以