时间和窗口一直是Flink在流处理领域的一个王牌武器,也是Flink的理论基石。在Flink中,时间和窗口分别代表着“时间语义”和“时间窗口”两个概念。之前我们学习了关于数据映射(map操作)、过滤(filter操作)、分组(keyBy操作)、归约聚合(reduce操作)等各类操作,Flink的功能在我们看来已经很丰富了,那么时间窗口和时间语义又是为何而生?又帮助我们解决了什么问题呢?
本章我们就来探究时间窗口和时间语义的奥秘。
如标题所示,作为本章的第一节,重点就是为了给大家的脑海中根植一个印象——时间窗口和时间语义两者密不可分。
那么什么是时间窗口和时间语义呢?
我们知道所有理论概念的诞生都离不开实际的应用场景,所以为了回答这个问题,笔者先列举3个常见的实时数据计算场景。
当我们仔细分析这3个场景中计算的实时指标时,会发现它们都可以被一个统一的计算模型所描述出来,即:每隔一段时间计算并输出过去一段时间内的数据统计结果。这个统一的计算模型就是时间窗口,其中的“每隔一段时间计算并输出”、“过去一段时间内的数据”、“统计结果”分别代表了时间窗口的3个重要属性。
接下来我们以每1min计算并输出过去1min内所有商品的累计销售额的案例来说明时间窗口计算模型的处理机制。如图5-1所示,输入数据流中的每一个圆圈代表商品的一条销售记录,圆圈内的数字代表商品销售额。那么按照时间窗口的计算模型的3个属性来剖析这个需求就得到时间窗口的计算频次为1min,时间窗口的大小为1min,时间窗口内的数据的处理逻辑是将商品销售额求和。接下来,按照时间窗口计算模型的计算的话,步骤总共分为以下3步。
图5-1 时间窗口计算模型的处理机制
注意: 左开右闭的区间[9:01:00,9:02:00)用于描述时间范围为大于等于9:01:00和小于9:02:00的时间窗口。
在看完了上述案例之后,相信大家对时间窗口计算模型已经有了初步的了解。接下来,我们再使用时间窗口计算模型重新描述一下开头提到的3个实时数据计算场景,会得到表5-1。
表5-1 使用时间窗口计算模型描述实时数据计算场景
场景 | 时间窗口的计算频次 | 时间窗口的大小 | 时间窗口内的数据的处理逻辑 |
---|---|---|---|
电商场景计算销售额 | 每隔1min计算 | 1min内 | 每种商品的销售额 |
直播间同时在线人数 | 每隔1min计算 | 1min内 | 人数 |
商品累计销量 | 每隔10s计算 | 商品上架后到当前时刻 | 累计销量 |
通过表5-1可以发现,使用时间窗口计算模型来描述这些指标的口径后,这3种实时计算场景中指标的计算逻辑会变的清晰且标准。值得一提的是,当我们将场景范围进一步扩大时,会发现大部分的实时指标,包括离线指标的计算过程都符合时间窗口计算模型。比如每天计算一次过去一天的商品GMV(商品交易总额),每小计算一次过去24小时GMV,这些离线指标的计算过程都可以用时间窗口计算模型来描述。
在明确了时间窗口计算模型的计算过程之后,接下来我们就要实际上手开发一个时间窗口的应用了,当我们想使用Flink大干一场时,却发现只用时间窗口来定义和描述指标口径还存在一个问题,这个问题就和本章的另一个重点——时间语义息息相关了。先总结一下这个问题:当我们按照时间窗口计算模型处理数据时,是使用数据真实发生的时间来计算,还是使用数据到达Flink时间窗口算子SubTask时的本地机器时间来计算呢?
其中以哪种时间用作时间窗口的计算就是时间语义要讨论的问题。
干巴巴的去说明这个问题不太容易理解。我们以上述场景2中的直播间同时在线人数为例,如图5-2所示,A、B两名用户分别在9:01:50和9:02:00观看了一场直播,并上报了两条观看直播的数据,但是由于网络传输存在延迟,这两条数据分别在9:03:00和9:03:01才到达Flink的SubTask中。
图5-2 数据经过传输之后到达SubTask中进行计算
在上面这个场景中,一条数据出现了两个不同的时间,第一个是事件发生时(数据产生时)的时间,第二个是数据到达SubTask的本地机器时间,如果使用第一个时间来进行时间窗口计算,那我们就称这个时间窗口的时间语义是事件时间,如果使用第二个时间来进行时间窗口计算,那我们就称这个时间窗口的时间语义是处理时间。而如果要执行时间窗口的计算,就需要我们选择其中一种时间语义,而核心问题就在于不同的时间语义计算得到的结果是不同的!如图5-3所示,假设我们选择处理时间语义用作时间窗口的计算,那么这两条数据的时间戳就是9:03:00和9:03:01,在进行计算时,这两条数据会被划分到[9:03:00,9:04:00)这个时间窗口中,并在SubTask本地时间到达9:04:00时触发[9:03:00,9:04:00)窗口的计算,计算得到的结果是在9:03:00到9:04:00这1min内有两名用户观看了直播。
图5-3 处理时间、事件时间语义下时间窗口计算模型的不同之处
如图5-3所示,假设我们选择事件时间语义用作时间窗口的计算,那么这两条数据的时间戳就是9:01:50、9:02:00。接下来进行计算时,这两条数据会被分别分配到[9:01:00,9:02:00)、[9:02:00,9:03:00)这两个时间窗口中进行计算,并在数据的时间到达9:02:00时计算一次[9:01:00,9:02:00)窗口内数据,在数据的时间到达9:03:00时计算一次[9:02:00,9:03:00)窗口内的数据。最终算得到的结果是这个直播间在9:01:00到9:02:00这1min有一名用户观看了直播,在9:02:00到9:03:00这1min也有一名用户观看了直播。
对比上述两种时间语义可以发现,以不同的时间语义去执行时间窗口计算,得到的结果将会完全不同,因此要想把时间窗口计算模型的计算逻辑完完全全的定义清楚,时间语义也是必不可少的,这也就是本节标题“时间窗口和时间语义这对好朋友”的由来。