赞
踩
|flink-1.9 docs:Apache Flink 1.9 Documentation: Windows
1. Flink是一种流式计算引擎,用于处理无界数据流。在处理无界流时,一种有效的方式是将无限的数据切割成有限的"数据块",这就是窗口(Window)的概念。
2. 在Flink中,窗口是用来处理无界流的核心概念。你可以将窗口想象成一个动态创建的数据存储桶,数据源源不断地流入这些存储桶。当某个时间点窗口需要关闭时,它停止收集数据、触发计算并输出结果。
3. 窗口的时间范围以左闭右开的区间表示,例如,0~10秒的窗口表示为[0, 10)。
4. 在处理时间窗口时,窗口的关闭是基于系统时间的,即当数据的时间戳超过窗口结束时间时,窗口关闭并触发计算。对于迟到的数据,它们会被分配给后续窗口,但可能会导致处理结果不准确。
5. 在事件时间语义下,由于可能存在乱序数据,需要设置延迟时间来等待所有数据到达。这可以确保包含迟到的数据并保持准确性。
6. 窗口实际上可以被理解为多个有限大小的“存储桶”,数据会根据时间戳分发到对应的存储桶中。当到达窗口结束时间时,对每个存储桶中的数据进行计算处理。
7. 窗口是动态创建的,只有在有数据到达时才会创建对应的窗口。窗口的触发计算和关闭可以分开执行,确保数据被准确处理。
总之,Flink中的窗口是用来处理无界数据流的重要机制,通过动态创建存储桶和设置事件时间语义来确保数据的正确处理。
窗口的分类可以按照不同的角度来进行划分:
这种窗口根据时间段来截取数据。窗口的开始和结束由时间点定义,数据在这个时间段内进行收集和计算。时间窗口可以基于处理时间或事件时间定义。
这种窗口根据数据元素的个数来截取数据。当达到固定的数据个数时,窗口触发计算并关闭。计数窗口不依赖时间,只关注数据个数。
滑动窗口也有固定的大小,但窗口之间可以有一定的重叠。窗口的滑动步长决定了窗口的触发频率。数据可能同时属于多个窗口,取决于窗口大小和滑动步长的比值。
滚动窗口有固定的大小,窗口之间没有重叠,数据被均匀切片。数据属于一个窗口,无论何时,窗口之间没有间隔。
会话窗口基于数据之间的时间间隔来截取数据。如果数据之间的间隔小于指定的时间(会话超时时间),它们属于同一个会话窗口。会话窗口的长度是不固定的,可以根据数据的活动来动态划分。
全局窗口将相同键(key)的所有数据分配到一个窗口中,没有窗口结束的时间点。触发计算需要自定义触发器。这种窗口通常用于需要更灵活处理的情况,如计数窗口的底层实现就是全局窗口。
Flink中有多种窗口类型可供选择,可以根据不同的需求和数据特性来选择适当的窗口类型。每种窗口类型都有其特定的应用场景和用途。
|flink-1.9 docs:Apache Flink 1.9 Documentation: Windows
在Flink中,窗口操作主要分为按键分区窗口(Keyed Windows)和非按键分区窗口(Non-Keyed Windows),具体如下:
1. 按键分区窗口(Keyed Windows): 在按键分区窗口中,数据流通过.keyBy()操作被按键分区成多个逻辑流(KeyedStream),每个逻辑流都对应一个特定的键(key)。窗口计算会在多个并行子任务上同时执行,相同键的数据会被发送到同一个并行子任务上进行窗口计算。这意味着每个键都有一组独立的窗口进行统计计算。
在代码中,按键分区窗口操作的典型调用顺序如下:
- //1、使用.keyBy()按键分区,将数据流按照键分成多个逻辑流。
- stream.keyBy(<key selector>)
- //2、使用.window()定义窗口,传入一个窗口分配器(Window Assigner),该分配器指定了窗口的类型和属性。
- .window(<window assigner>)
- //3、使用.aggregate()或其他窗口函数定义窗口的处理逻辑
- .aggregate(<window function>)
2. 非按键分区窗口(Non-Keyed Windows): 如果没有进行.keyBy()按键分区,原始的DataStream不会分成多个逻辑流,窗口操作将在一个任务上执行,即并行度为1。一般情况下,不推荐使用非按键分区窗口,因为它无法充分利用并行性。
在代码中,非按键分区窗口操作的调用方式如下:
stream.windowAll(<window assigner>)
总之,窗口操作需要先确定是按键分区窗口还是非按键分区窗口,然后根据需求使用相应的API调用来定义窗口分配器和窗口函数,以实现窗口计算。通常情况下,按键分区窗口更常见和有用,因为它能够更好地利用并行性。
|flink-1.9 docs:Apache Flink 1.9 Documentation: Windows
窗口分配器实际上是用于确定窗口类型的工具之一。
通常,最常见的定义方法是使用.window()方法,该方法需要传入一个WindowAssigner作为参数,并返回一个WindowedStream对象。
对于非按键分区窗口,可以直接使用.windowAll()方法,同样需要传入一个WindowAssigner,返回的是AllWindowedStream。
时间窗口是最常用的窗口类型,又可以细分为滚动、滑动和会话三种
- stream.keyBy(...)
- .window(TumblingProcessingTimeWindows.of(Time.seconds(5)))
- .aggregate(...);
使用场景:适用于周期性统计,比如每5秒钟计算一次统计数据。
- stream.keyBy(...)
- .window(SlidingProcessingTimeWindows.of(Time.seconds(10), Time.seconds(5)))
- .aggregate(...);
使用场景:适用于连续统计,可以用于监控系统中的滚动平均值计算。
- stream.keyBy(...)
- .window(ProcessingTimeSessionWindows.withGap(Time.seconds(10)))
- .aggregate(...);
使用场景:用于处理连续的会话数据,例如用户在应用中的活动会话,会话之间的间隔超过一定时间会被视为不同的会话。
- stream.keyBy(...)
- .window(ProcessingTimeSessionWindows.withDynamicGap(new SessionWindowTimeGapExtractor<Tuple2<String, Long>>() {
- @Override
- public long extract(Tuple2<String, Long> element) {
- // 提取session gap值返回, 单位毫秒
- return element.f0.length() * 1000;
- }
- }))
- .aggregate(...);
- stream.keyBy(...)
- .window(TumblingEventTimeWindows.of(Time.seconds(5)))
- .aggregate(...);
场景:适用于处理数据流中的事件,例如实时日志分析、事件时间的流式处理等。
- stream.keyBy(...)
- .windo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。