前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flink 窗口之Window机制

Flink 窗口之Window机制

作者头像
smartsi
发布2021-02-04 16:06:43
1.3K0
发布2021-02-04 16:06:43
举报
文章被收录于专栏:SmartSi

数据分析场景见证了批处理到流处理的演变过程。尽管批处理可以作为流处理的一种特殊情况来处理,但分析永无止境的流数据通常需要转变一种思维方式,并使用它自己的专门术语,例如,窗口、At-Least-Once 或者 Exactly-Once 处理语义。

对于刚刚接触流处理的人来说,这种思维方式的转变以及新的专业术语可能会让他们感到非常困惑。但是,Apache Flink 作为一个为生产环境而生的流处理器,具有易于使用并且表达能力很强的 API 来定义高级流分析程序。 Flink 的 API 在数据流上有非常灵活的窗口定义,使其能在其他开源流处理器中脱颖而出。

在这篇文章中,我们主要讨论用于流处理的窗口的概念,介绍 Flink 的内置窗口,并说明其对自定义窗口语义的支持。

1. 什么是窗口?它们有什么用?

我们拿交通传感器的例子来说明,传感器每15秒统计通过某个位置的车辆数量。结果流看起来像如下所示:

如果现在我们想知道有多少辆车经过这个位置,我们只需简单的将每15秒统计的数量相加即可。但是,传感器流的本质是连续产生数据。像这样的流永远都不会结束,更不可能计算出可以返回的最终和。换一种思路,我们可以滚动计算总和,即为每个输入事件返回一个更新的总和记录。这就会产生新的部分和流:

但是,部分求和流可能不是我们想要的,因为它会不断更新计数,更重要的是,某些信息(例如随时间变化)会丢失。因此,我们需要想改一下我们的问题:每分钟通过该位置的汽车数量。这要求我们将流的元素分组为有限的集合,每个集合对应于60秒。此操作称为滚动窗口操作。

滚动窗口将流离散化为不重叠的窗口。对于某些应用程序,重要的是窗口不可分离,因为应用程序可能需要平滑的聚合。例如,我们可以每30秒计算最后一分钟通过的汽车数量。这种窗口称为滑动窗口。

如上所述,在数据流上定义窗口是非并行操作。这是因为流的每个元素必须由同一窗口算子处理,决定每个元素应归属到哪个窗口中。一个完整流上的 Windows 在 Flink 中称为 AllWindows。对于许多应用程序,数据流可以拆分为多个逻辑流,每个逻辑流都可以应用窗口算子。例如,考虑统计来自多个交通传感器(而不是像前面的示例中的一个传感器)的车辆,其中每个传感器都会监控一个不同的位置。通过按传感器ID对流进行分组,我们可以并行计算每个位置的窗口流量统计。在 Flink 中,我们将这种分区的窗口简称为 Windows,因为它们是分布式流的常见情况。下图显示了在 (sensorId, count) 流上的滚动窗口。

一般来说,窗口在无界流上定义了一组有限的元素。该集合可以基于时间(如我们之前的示例中所示),元素个数,元素个数和时间的组合或一些自定义逻辑将元素分配给窗口。Flink 的 DataStream API 为最常见的窗口操作提供了简洁的算子,并提供了一种通用的窗口机制,该机制允许用户自定义窗口逻辑。在下面的内容中,我们将介绍 Flink 的 Time Windows 和 Count Windows,然后再详细讨论其窗口机制。

2. Time Windows

顾名思义,Time Windows(时间窗口)按时间对流元素进行分组。例如,窗口大小为一分钟的滚动窗口将收集一分钟内的元素,并在一分钟后将函数应用于窗口中的所有元素。在 Apache Flink 中定义滚动和滑动时间窗口非常简单:

代码语言:javascript
复制
// Stream of (sensorId, carCnt)
DataStream<Tuple2<String, Long>> vehicleCnt ...

// 滚动窗口
DataStream<Tuple2<String, Long>> tumblingCnt = vehicleCnt
        // 根据sensorId分组
        .keyBy(0)
        // 窗口大小为1分钟的滚动窗口
        .timeWindow(Time.minutes(1))
        // 求和
        .sum(1);

// 滑动窗口
DataStream<Tuple2<String, Long>> slidingCnt = vehicleCnt
        // 根据sensorId分组
        .keyBy(0)
        // 窗口大小为1分钟、滑动步长为30秒的滑动窗口
        .timeWindow(Time.minutes(1), Time.seconds(30))
        // 求和
        .sum(1);

我们还没有讨论过 ‘收集一分钟内的元素’ 的确切含义,也可以归结为’流处理器如何解释时间?’这一问题。

Apache Flink 具有三种不同的时间概念,即处理时间,事件时间和摄取时间。具体的可以参阅Flink 事件时间与处理时间

3. Count Windows

除了 Time Windows 外,Apache Flink 还具有 Count Windows(计数窗口)。一个大小为100的滚动计数窗口,将会在一个窗口中收集100个元素,并在添加第100个元素时触发窗口计算。

在 Flink 的 DataStream API 中,滚动和滑动计数窗口如下定义:

代码语言:javascript
复制
// Stream of (sensorId, carCnt)
DataStream<Tuple2<String, Long>> vehicleCnt ...

// 滚动窗口
DataStream<Tuple2<String, Long>> tumblingCnt = vehicleCnt
        // 根据sensorId分组
        .keyBy(0)
        // 100个元素大小的滚动计数窗口
        .countWindow(100)
        // 求和
        .sum(1);

// 滑动窗口
DataStream<Tuple2<String, Long>> slidingCnt = vehicleCnt
        // 根据sensorId分组
        .keyBy(0)
        // 100个元素大小、步长为10个元素的滑动计数窗口
        .countWindow(100, 10)
        // 求和
        .sum(1);

4. 剖析Flink的窗口机制

Flink 的内置 Time Windows 和 Count Windows 覆盖了各种常见的窗口用例。但是,有些应用程序还是需要实现自定义窗口逻辑,而 Flink 的内置窗口无法解决这些逻辑。为了同时也支持定制的窗口语义的应用程序,DataStream API 公开了窗口机制内部的接口。这些接口可以非常精细地控制窗口的创建和触发。

下图描述了 Flink 的窗口机制,并介绍了其中涉及的组件。

图片

到达窗口算子的元素将传递给 WindowAssigner。 WindowAssigner 将元素分配给一个或多个窗口,也可能会创建新的窗口。窗口本身只是一系列元素的标识符,并且可以提供一些可选的元信息,例如,在使用 TimeWindow 时的开始和结束时间。请注意,可以将元素添加到多个窗口中,这也意味着可以同时存在多个窗口。

每个窗口都有一个 Trigger,决定了何时触发计算或清除该窗口。当先前注册的计时器到点时,对于分配到窗口中的每个元素都会调用 Trigger。对于每个事件,Trigger 都可以决定触发,清除(清除窗口并丢弃其内容),或者触发并清除窗口。仅触发的 Trigger 会计算窗口并保持其原样,即所有元素都保留在窗口中,并在下次触发时再次计算(不删除元素)。一个窗口可以被触发多次计算,并且一直存在直到清除为止。请注意,在清除窗口之前,窗口会一值消耗内存。

触发 Trigger 时,可以将窗口元素列表提供给可选的 Evictor。Evictor 遍历列表,可以决定从列表的开头删除一些元素,即删除一些首先进入窗口的元素。其它元素则提供给窗口计算函数。如果没有定义 Evictor,则 Trigger 直接将所有窗口元素交给窗口计算函数。

窗口计算函数接收一个窗口的元素(可能先由 Evictor 进行过滤),并为该窗口计算一个或多个结果元素。DataStream API 可以接受不同类型的计算函数,包括预定义的聚合函数,例如,sum(),min(),max() 以及 ReduceFunction,FoldFunction 或 WindowFunction。WindowFunction 是最通用的窗口计算函数,接收窗口对象(即窗口的元数据),窗口元素列表以及窗口键(如果是 Keyed Window)作为参数。

这些是构成 Flink 的窗口机制的组件。

5. 结论

对于现代流处理器来说,在连续数据流上支持各种类型的窗口是必不可少的。Apache Flink 是一种流处理器,具有非常强大的功能,其中就包括一种非常灵活的机制来构建和计算连续数据流上的窗口。Flink 为常见用例提供了内置的窗口算子,以及允许用户自定义窗口逻辑。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是窗口?它们有什么用?
  • 2. Time Windows
  • 3. Count Windows
  • 4. 剖析Flink的窗口机制
  • 5. 结论
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档