一、时间分类
flink支持三种不同概念的时间
- 事件时间 (event time)
事件发生的时间
- 提取时间 (ingest time)
flink读取事件的时间
- 处理时间(processing time)
flink算子开始处理事件的时间
二、Event Time 使用场景
- 分析历史数据
需要基于事件的发生的时间,这样分析出来的结果才正确,不依赖什么时候去分析。
- 测试新的接口
需要保证新旧接口的输出一致,则需要基于事件时间。
- 某些实时应用
三、水位线(Watermarks)
使用event time,必须要使用watermarks, 需要提供 Timestamp Extractor(从事件中提取时间) 和 Watermark Generator (水位线生成器)
3.1 什么是水位线
Watermark是一种衡量event-time 进展的机制,用来处理数据中的乱序问题,通常watermark结合窗口使用。
3.2 水位线作用以及机制
通过一个例子来说明。
以下是一个乱序的实时的event time流,数字表示事件发生的时间,第一个到达的事件是4,后续的2比4发送的更早
··· 23 19 22 24 21 14 17 13 12 15 9 11 7 2 4 →
要求:根据这个乱序的流 生成一个根据event time有序的流
观察结果:
(1)有序流看到的第一个事件是4,但是不能立刻作为有序流的第一个元素。它可能是乱序到达的,后面可能还有更早的事件到达。根据上面的无序流,明显可知需要等到事件2到达后才能生成结果。
缓存、延迟
需要将4缓存起来,因为缓存后,不能立刻处理,所以有一定的延迟
(2)如果做错了,将永远的等待下去。第一个事件是4,第二个事件是2,那后续还有比2早的时间么 ?可能有,也可能没有。在这里将等待时间1的到来,但是永远都没有1。
什么时候不再等待?
事实上,这里不得不将2作为有序流的第一个结果输出
(3) 对于时间事件,需要定义策略,什么时候停止等待更早的事件
整个恰恰是watermarks做的事情 ----定义什么时候停止等待更早的事件
Flink处理Event time使依赖watermark 生成器,插入具体时间的元素进入到流中,这个操作称为watermarks.
对于时间t的watermark 表示流时间t之前(可能)已经完成。
什么时候这个流停止等待,并且将2输出到有序流中呢? 这里是当事件2到达或者更大的事件。
(4) 你或许想象不同的策略去决定如何生成watermarks
每个事件在延迟之后到达,这些延迟是不同的,所以有些事件延迟的时间比其他事件要长。
一个简单的方法是假定这些延迟受到某个最大延迟的限制。Flink将这种策略称为有界无序watermarks。
很容易想象出更复杂的水印方法,但对于大多数应用程序来说,固定的延迟就足够了。
3.3 延迟和完整性
对于开发者来说,在延迟和完整性之间进行平衡也是对watermarks另一方面的考虑。
不像批处理,在批处理过程中,用户可以在处理前就对数据有完整的了解,而流处理,必须停止等待,生成结果。
- 通过配置低延迟的边界,快速的生成watermarks, 这样能快速的产生结果,但是结果可能是错误的;
- 也可以配置长时间的等待来产生更完整的结果。
- 可以混合使用,快速的产生结果,然后对额外的数据进行处理,更新相应的结果,这对一些应用也是一种不错的方法