Flink中的水位线
一、时间语义
在介绍水位线之前,需要引入时间语义的概念。Flink中的时间语义有两种,事件时间和处理时间。事件时间就是数据产生时的时间,处理时间是数据被处理时的时间。水位线是与事件时间相关的概念
二、水位线
我们在窗口的处理过程中定义了一个基于数据时间戳的“逻辑时钟”,这个逻辑时钟的数据不会自动流逝,他是靠着新数据的到来来推动逻辑时钟的改变的。
这个“逻辑时钟”就是水位线。它是一条特殊的数据记录,其主要内容就是时间戳,用来衡量事件时间的进展。
(1)、有序流中的水位线
1.1、理想状态下(数据量小),数据应该按照生成的先后顺序进入流中,然后为每进入的一条数据都生成一个水位线,这个水位线中的时间戳内容就是新进入的数据的事件时间。
1.2、上述只是理想情况,但是实际中流入的数据量非常大,且同时涌来的数据的时间差很小,如果为每条数据都生成一条水位线极大地浪费资源。因此针对这样的情况,我们不必为每条数据生成一条水位线,可以每个一段时间来生成一个水位线。
(2)、无序流中的水位线
在数据传入的过程中由于网络传输时延等不确定因素,传到的数据并不一定都是有序的,可能是乱序的,针对这种乱序场景:
2.1、乱序+数据量小
在每来一条数据时,会为其生成一个水位线,水位线中的时间戳就是这条数据的事件时间。当下一条数据来之后,会让其事件时间与水位线进行对比,如果事件时间大于水位线,则生成新的水位线,如果事件时间小于等于水位线,则不必再生成新的水位线。
2.2、乱序+数据量大
在流入数据量非常大,且同时流入的数据的时间差很小的情况下,可以考虑相隔一段时间才生成水位线,每次更新水位线都是拿这一段时间间隔中最大的事件时间与水位线进行对比,如果大于水位线,则会更新水位线中的时间戳,如果小于等于水位线,则不会再更新水位线。
2.3、乱序+迟到数据
有时候有些数据会迟于水位线的时间戳到达,这种情况很常见。Flink的解决办法是得到的水位线减去一定的时间间隔才是真正的水位线。当这个水位线到达窗口的截止时间的时候就会开始去处理窗口中的数据,后面新到达的数据就不会再接收。
(3)、水位线的特性
水位线是插入到数据流中的一个标记,可以认为是一个特殊的数据;
水位线的主要内容是一个时间戳,用来表示事件时间的进展;
水位线的时间戳是单调递增的,以确保任务的事件时间时钟一直向前推进;
水位线可以通过设置延迟来等待迟来的数据;
水位线到达了时间戳t,就表示t时间之间的所有数据都到齐了,之后流中不会出现小于t时间的数据。