时间语义

  • java
  • flink
  • 时间语义

一、时间语义

flink是一个有状态的流处理框架,在处理状态时经常会遇见与时间有关操作,例如:时间窗口、定时器、迟到的数据、trigger等等。

这些操作都与时间有关,那么问题来了,这个时间以谁为准?是日志里自己带的时间字段?还是flink接收到日志的时间?

  • Event Time:事件时间。一般就是从日志中代表事件发生时间的字段提取出来的时间
  • Ingestion Time:摄入时间。日志被Flink摄入的时间 (一直没用过🐶)
  • Processing Time:处理时间。被处理时机器的系统时间

Ingestion Time与Processing Time区别。Ingestion Time的时间在datasource处被分配,而Processing Time在到达需要水位线的算子处被分配

二、水位线

水位线(Watermark)是为了处理乱序数据而产生的,flink的水位线应该就是是借鉴自音视频开发中水位线的概念🐶

不同的是flink水位线可以设置的很大,可以到分钟级别,而音视频的水位线一般都是毫秒级别的。

2.1 数据乱序、数据迟到

在处理流数据的时候,我们肯定是希望数据是有序的,并且计算出的结果是唯一的。

试想,如果同一批数据因为被处理的先后顺序不一致,就可能导致的计算结果千奇百怪。

2.2 延迟处理

这里以Event Time为例。

延迟处理是解决数据乱序问题的一种方案。比如一个1分钟Event Time的窗口,根据数据的Event Time延迟10s,那么触发这个窗口计算的时间会延长10s甚至更多,等到大于这个窗口右边界的时间10s的事件到达时,才会触发窗口计算。

在这个10s甚至更多的时间内,可能会有一些迟到的数据到达,不过没关系,以为窗口还没有计算并关闭,这些数据依然会被接收并参与到窗口的计算。

等到大于这个窗口右边界的时间10s的事件到达时,会触发窗口计算,此时如果有迟到的数据到达,就会被丢弃。当然也可以通过allowLateNess设置允许事件迟到的时长,允许窗口计算之后,迟到的事件再次参与到窗口的计算中去。

窗口计算时再按照事件的Event Time的顺序处理,就尽可能的解决了数据乱序+迟到的问题。

2.3 到底什么事水位线

上面说了这么多,也没具体提到watermark到底是什么。举个例子,假设:

  • 当前事件时间是10:00:30
  • 延迟时间10s
  • 窗口范围10:00:10~10:00:20

那么此时的水位线就是10:00:20,正好是窗口的右边界,此时窗口会被触发计算。

换句话说就是大于等于窗口右边界的事件出现了,此时窗口会被触发计。

Loading...