Time
时间分类
EventTime(事件发生时间):
事件发生的时间,例如:点击网站上的某个链接的时间,每一条日志都会记录自己的生成时间如果以EventTime为基准来定义时间窗口那将形成EventTimeWindow,要求消息本身就应该携带EventTime
IngestionTime(数据被Flink的Source加载的时间):
数据进入Flink的时间,如某个Flink节点的source operator接收到数据的时间,例如:某个source消费到kafka中的数据如果以IngesingtTime为基准来定义时间窗口那将形成IngestingTimeWindow,以source的systemTime为准
ProcessingTime(真正被Flink计算的时间):
某个Flink节点执行某个operation的时间,例如:timeWindow处理数据时的系统时间,默认的时间属性就是Processing Time如果以ProcessingTime基准来定义时间窗口那将形成ProcessingTimeWindow,以operator的systemTime为准
在Flink的流式处理中,绝大部分的业务都会使用EventTime,
一般只在EventTime无法使用时,
才会被迫使用ProcessingTime或者IngestionTime。
如果要使用EventTime,那么需要引入EventTime的时间属性,
引入方式如下所示:
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) //设置使用事件时间
Flink情景:
示例1
现在假设,你正在去往地下停车场的路上,并且打算用手机点一份外卖。选好了外卖后,你就用在线支付功能付款了,这个时候是11点50分。恰好这时,你走进了地下停车库,而这里并没有手机信号。因此外卖的在线支付并没有立刻成功,而支付系统一直在Retry重试“支付”这个操作。当你找到自己的车并且开出地下停车场的时候,已经是12点05分了。这个时候手机重新有了信号,手机上的支付数据成功发到了外卖在线支付系统,支付完成。在上面这个场景中你可以看到,支付数据的事件时间是11点50分,而支付数据的处理时间是12点05分问题:如果要统计12之前的订单金额,那么这笔交易是否应被统计?应该被统计,因为该数据的真真正正的产生时间为11:50,即该数据的事件时间为11:50,所以一般在实际开发中会以事件时间作为计算标准
示例2
一条日志进入Flink的时间为2019-08-12 10:00:01,
摄入时间到达Window的系统时间为2019-08-12 10:00:02,
处理时间日志的内容为:2019-08-12 09:58:02
事件时间对于业务来说,要统计1h内的故障日志个数,哪个时间是最有意义的?
—事件时间EventTime,因为我们要根据日志的生成时间进行统计。
示例3:
某 App 会记录用户的所有点击行为,并回传日志(在网络不好的情况下,先保存在本地,延后回传)。A 用户在 11:02 对 App 进行操作,B 用户在 11:03 操作了 App,但是 A 用户的网络不太稳定,回传日志延迟了,导致我们在服务端先接受到 B 用户 11:03 的消息,然后再接受到 A 用户 11:02 的消息,消息乱序了。那么,如果这个是一个根据用户操作先后顺序,进行抢购的操作,那么是A用户成功还是B用户成功?应该是根据数据的产生时间来判断,也就是A是11:02操作的,B是11:03操作的,尽管因为网络延迟,A的数据比B的数据晚到,但是也应该算A成功(当然实际中考虑到实现难度,可能直接按B成功算)
示例4:
在实际环境中,经常会出现,因为网络原因,数据有可能会延迟一会才到达Flink实时处理系统。我们先来设想一下下面这个场景:
- 使用时间窗口来统计10分钟内的用户流量
- 有一个时间窗口 - 开始时间为:2017-03-19 10:00:00 - 结束时间为:2017-03-19 10:10:00
- 有一个数据,因为网络延迟
事件发生的时间为:2017-03-19 10:10:00
但进入到窗口的时间为:2017-03-19 10:10:02,延迟了2秒中4.
时间窗口并没有将59这个数据计算进来,
导致数据统计不正确
这种处理方式,根据消息进入到window时间,来进行计算。在网络有延迟的时候,会引起计算误差。如何解决?
解决方法:flink在这样的延迟情景中提出了”水印机制“也可以称为“水位线”(watermark)
使用Watermark解决延迟问题说明及步骤:
水印(watermark)就是一个时间戳,Flink可以给数据流添加水印,可以理解为:收到一条消息后,额外给这个消息添加了一个时间字段,这就是添加水印。- 水印并不会影响原有Eventtime事件时间- 当数据流添加水印后,会按照水印时间来触发窗口计算也就是说watermark水印是用来触发窗口计算的- 一般会设置水印时间,比事件时间小几秒钟,表示最大允许数据延迟达到多久