关于Flink中time与watermark的理解

关于Flink中time与watermark的理解

空间和时间只是我们人类思考的模式,并不是我们赖以生存的条件。
——爱因斯坦

时间属性是流处理中最重要的一个方面,是流处理系统的基石之一;流计算是一种无限数据形式,如果没有时间属性,许多问题将不能解决,下面将列举和时间列紧密相关,或者说必须在这个时间列上才能进行的操作:
Over 窗口聚合
Group by 窗口聚合
OrderBy 排序
时间概念:
在flink中,时间的核心是 Processing Time 和 Event Time(Row Time);Processing Time,即事件被处理的时间。处理时间其实就是处理事件的机器所测量的时间;事件时间,即事件实际发生的时间。更准确地说,每一个事件都有一个与它相关的时间戳,并且时间戳是数据记录的一部分(比如手机或者服务器的记录)。事件时间其实就是时间戳。
两者的概念中我觉得以下的解释相当好:
关于Flink中time与watermark的理解
时间是人为的一种规定,一天24小时,是地球自传一周,一年是地球饶太阳一周,时间是一种运动;Processing Time是现在正在出现,发生的时间,是真实世界中时间;Event Time时间,是某个世界的时间,就像精灵宝可梦中,小智几个月收集了几只神奇宝贝,是精灵宝可梦世界的时间,又如“怀旧空吟闻笛赋,到乡翻似烂柯人”中观棋一局,已过百年;Event Time时间是数据在它的那个世界中的时间,以时间戳的形式告诉你。
这就引出了其中不同的问题,Processing Time结果是不可复现的,一旦流式计算版本升级甚至系统崩溃,计算将会停止,你需要从以前的一个时间点开始继续,但是“人不能踏入同一条河流”,现实的那个世界已经流逝,起码现在的科技不能重现,所以流式计算重跑的结果是不确定的,Processing Time处理问题简单、轻便,适用于对结果可溯要求不高的场景。
Event Time时间属性,虽然可塑性强,只要找到那个时间,一定还是原来的结果,但是他有乱序的问题,可能由于网络延迟、分布式系统等等原因导致,某些数据来的比较晚,可能这个时间戳的事务已经处理完毕,这个时间刚刚来,为了应对这种问题其中之一的方法就是watermark。
首先了解一下窗口的概念:
窗口是一种机制,它用于将许多事件按照时间或者其他特征分组,从而将每一组作为整体进行分析(比如求和);Flink 提供了几种通用的 窗口:滚动窗口(窗口间的元素无重复),滑动窗口(窗口间的元素可能重复),计数窗口,会话窗口 以及全局窗口(类似批处理)。如果需要自己定制数据分发策略,则可以实现一个 class,继承自 WindowAssigner。
关于Flink中time与watermark的理解
滚动窗口
关于Flink中time与watermark的理解
滚动窗口
关于Flink中time与watermark的理解
会话窗口
在 Event Time 场景下,我们把每一个记录所包含的时间称作 Record Timestamp。如果 Record Timestamp 所得到的时间序列存在乱序,我们就需要去处理这种情况。
关于Flink中time与watermark的理解
这是单条数据之间是乱序,我们对于整个序列进行更大程度的离散化。简单地讲,就是把数据按照一定的条数组成一些小批次,但这里的小批次并不是攒够多少条就要去处理一样的批处理,而是为了对他们进行时间上的划分。经过这种更高层次的离散化之后,我们会发现最右边方框里的时间就是一定会小于中间方框里的时间,中间框里的时间也一定会小于最左边方框里的时间。
关于Flink中time与watermark的理解
watermark类似于一种标志,这种标志体现以后出现的时间都将大于此标志的时间戳;它的存在使得我们一个有效的进度指标,可以安全输出这个窗口的聚合结果。这只是解决了乱序的问题,而乱序的本质实际上是数据迟到,watermark并不能完全解决数据迟到的问题,生成 watermark(t) 之后,还有较小的概率接受到时间戳 t 之前的数据,在 Flink 中将这些数据定义为 “late elements”,可以在窗口中使用下面的代码进行设置(一般使用watermark即可,默认延迟的最大时间为0):
关于Flink中time与watermark的理解
参考文献;
Friedman E , Tzoumas K . Introduction to Apache Flink: Stream Processing for Real Time and Beyond[J]. 2016.
阿里大神们.零基础入门:从0到1学会Apache Flink[电子书].2019