2021年大数据Flink(二十二):Time与Watermaker

2021-10-11 09:57:23 浏览数 (1)


Flink-Time与Watermaker

Time分类

在Flink的流式处理中,会涉及到时间的不同概念,如下图所示:

事件时间EventTime: 事件真真正正发生产生的时间

摄入时间IngestionTime: 事件到达Flink的时间

处理时间ProcessingTime: 事件真正被处理/计算的时间

问题: 上面的三个时间,我们更关注哪一个?

答案: 更关注事件时间 !

因为: 事件时间更能反映事件的本质! 只要事件时间一产生就不会变化

EventTime的重要性

示例1

假设,你正在去往地下停车场的路上,并且打算用手机点一份外卖。选好了外卖后,你就用在线支付功能付款了,这个时候是11点59分。恰好这时,你走进了地下停车库,而这里并没有手机信号。因此外卖的在线支付并没有立刻成功,而支付系统一直在Retry重试“支付”这个操作。

当你找到自己的车并且开出地下停车场的时候,已经是12点01分了。这个时候手机重新有了信号,手机上的支付数据成功发到了外卖在线支付系统,支付完成。

在上面这个场景中你可以看到,

支付数据的事件时间是11点59分,而支付数据的处理时间是12点01分

问题:

如果要统计12之前的订单金额,那么这笔交易是否应被统计?

答案:

应该被统计,因为该数据的真真正正的产生时间为11点59分,即该数据的事件时间为11点59分,

事件时间能够真正反映/代表事件的本质! 所以一般在实际开发中会以事件时间作为计算标准

​​​​​​​示例2

一条错误日志的内容为:

2020-11:11 22:59:00 error NullPointExcep --事件时间

进入Flink的时间为2020-11:11 23:00:00    --摄入时间

到达Window的时间为2020-11:11 23:00:10 --处理时间

问题:

对于业务来说,要统计1h内的故障日志个数,哪个时间是最有意义的?

答案:

EventTime事件时间,因为bug真真正正产生的时间就是事件时间,只有事件时间才能真正反映/代表事件的本质!

​​​​​​​示例3

某 App 会记录用户的所有点击行为,并回传日志(在网络不好的情况下,先保存在本地,延后回传)。

A用户在 11:01:00 对 App 进行操作,B用户在 11:02:00 操作了 App,

但是A用户的网络不太稳定,回传日志延迟了,导致我们在服务端先接受到B用户的消息,然后再接受到A用户的消息,消息乱序了。

问题:

如果这个是一个根据用户操作先后顺序,进行抢购的业务,那么是A用户成功还是B用户成功?

答案:

应该算A成功,因为A确实比B操作的早,但是实际中考虑到实现难度,可能直接按B成功算

也就是说,实际开发中希望基于事件时间来处理数据,但因为数据可能因为网络延迟等原因,出现了乱序,按照事件时间处理起来有难度!

​​​​​​​示例4

在实际环境中,经常会出现,因为网络原因,数据有可能会延迟一会才到达Flink实时处理系统。我们先来设想一下下面这个场景:

原本应该被该窗口计算的数据因为网络延迟等原因晚到了,就有可能丢失了

​​​​​​​总结

实际开发中我们希望基于事件时间来处理数据,但因为数据可能因为网络延迟等原因,出现了乱序或延迟到达,那么可能处理的结果不是我们想要的甚至出现数据丢失的情况,所以需要一种机制来解决一定程度上的数据乱序或延迟到底的问题!也就是我们接下来要学习的Watermaker水印机制/水位线机制

Watermaker水印机制/水位线机制

什么是Watermaker?

Watermaker就是给数据再额外的加的一个时间列

也就是Watermaker是个时间戳!

​​​​​​​如何计算Watermaker?

Watermaker = 数据的事件时间  -  最大允许的延迟时间或乱序时间

注意:后面通过源码会发现,准确来说:

Watermaker = 当前窗口的最大的事件时间  -  最大允许的延迟时间或乱序时间

这样可以保证Watermaker水位线会一直上升(变大),不会下降

​​​​​​​Watermaker有什么用?

之前的窗口都是按照系统时间来触发计算的,如: [10:00:00 ~ 10:00:10) 的窗口,

一但系统时间到了10:00:10就会触发计算,那么可能会导致延迟到达的数据丢失!

那么现在有了Watermaker,窗口就可以按照Watermaker来触发计算!

也就是说Watermaker是用来触发窗口计算的!

​​​​​​​Watermaker如何触发窗口计算的?

窗口计算的触发条件为:

  1. 窗口中有数据
  2. Watermaker >= 窗口的结束时间

因为前面说到

Watermaker = 当前窗口的最大的事件时间  -  最大允许的延迟时间或乱序时间

也就是说只要不断有数据来,就可以保证Watermaker水位线是会一直上升/变大的,不会下降/减小的

所以最终一定是会触发窗口计算的

注意:

上面的触发公式进行如下变形:

Watermaker >= 窗口的结束时间

Watermaker = 当前窗口的最大的事件时间  -  最大允许的延迟时间或乱序时间

当前窗口的最大的事件时间  -  最大允许的延迟时间或乱序时间  >= 窗口的结束时间

当前窗口的最大的事件时间  >= 窗口的结束时间  最大允许的延迟时间或乱序时间

​​​​​​​图解Watermaker

0 人点赞