大数据理论篇 No.2-聊聊Flink流计算中的Timestamp和Watermark

第1章 时间语义

Flink里定义了三种时间语义:Event Time、Ingestion Time、Processing Time。

在整个流计算过程中,他们分别代表事件发生的时间数据最早进入Flink的时间数据被Flink算子处理时算子本地的时间

Event Time:事件发生时间,现实世界中数据真实产生的时间。无论数据流在传输和计算过程中花了多少时间EventTime是不会变的,它在时间发生时就已经确定。

Ingestion Time:数据最早进入Flink的时间,也就是数据到达Source的时间,Ingest Time同样不受内部算子计算和数据传输效率所影响。

Processing Time:数据进入每个算子时,算子所在机器上的本地时间。Process Time只依赖当前算子所在机器的系统时钟。

 

第2章 Timestamp

EventTime模式下,Flink从Source流入的所有数据都会包含Timestamp,这里的所指的Timestamp代表的是事件发生的时间。当然也可以是自定义的Timestamp。但是一定要保证时间戳的递增性。

举个例子,在业务上我们经常需要用到的窗口计算,计算某时间端内事件发生的次数:计算近两周内各地区确诊病例的数量,计算近一个小时各模块的访问量和用户点击量,等等……,这些都需要EventTIme模式下利用Timestamp做窗口计算。

在Flink里,Timestamp被定义为8字节的long值。每个算子拿到数据时,默认以毫秒精度的Unix时间戳解析这个long值,也就是自1970-01-01 00:00:00.000以来的毫秒数。当然自定义的算子可以自己定义时间戳的解析方式。

但是基于时间的应用,由于每个计算单元的计算能力不同、网络传输的速率也不同,而且现今大数据系统都是分布式架构。因为这些种种原因,数据到达Source和每一个计算单元都会存在一定的不确定性,这就是时间乱序问题。接下来我们看看Flink如何解决这种数据的乱序问题:Watermark。

第3章 Watermark

Flink定义了Watermark,它是一种数据元素StreamElement,和普通数据一起在算子之间传输。本质上是一个long类型的Timestamp,是一个全局进度指标。

Watermark可以在Source位置发射,也可以在流传输的任何算子上产生,并通过拓扑中的运算符传播。

在FLink流计算过程中,既然数据传输会有延迟,数据会产生乱序,那么在我们该在什么时候触发窗口计算呢?换一个思路,可以这么说:我们该如何知道要等多久才能确定窗口计算的数据都已经全部到达算子了呢?

我们来看上面这张图,Flink利用穿插在数据流当中的Watermark,Watermark让算子确信不会再有延迟事件到来,从而触发算子做窗口计算。那实际上在Watermark之后到底还会不会有该窗口的数据被遗漏呢?上面的示意图就已经解答了这个问题:可能会有。如果Watermark定义的延迟越小,那么存在遗漏可能性就越大;Watermark延迟定义的延迟越大,遗漏的可能性就越小,但是这也意味着,窗口触发的延迟越久。

所以Watermark在通常情况下,是需要自己根据自己的业务,去实际的测试调整,达到一个均衡值。在有些情况下,用户为了降低计算的延迟,又希望不直接舍弃那些被Watermark排除在外的数据,那么可以将这些数据写入日志或者利用这些数据去修正之前的结果。

最后多一句嘴:基于Processing Time的窗口计算不需要Watermark。

猜你喜欢

转载自blog.csdn.net/dzh284616172/article/details/109250973