当前位置:网站首页 > Haskell函数式编程 > 正文

窗口函数 聚合函数(窗口函数原理)



文章目录

  • Flink总结之一文彻底搞懂时间和窗口
  • 一、Flink中时间概念
  • 1. 事件时间(Event Time)
  • 2. 处理时间(Processing Time)
  • 3. 摄入时间(Ingestion Time)
  • 二、水位线(Watermark)
  • 1. 什么是水位线
  • 2. 水位线分类
  • 1. 有序流中的水位线
  • 1、如何使用
  • 2. 乱序流中的水位线
  • 2.1 乱序流中如何保证数据的准确性
  • 2.2 如何使用
  • 三、窗口
  • 1. 什么是窗口
  • 2. 窗口分类
  • 1. 按照驱动类型分
  • 1. 计数窗口(Count Window)
  • 2. 时间窗口(Time Window)
  • 1. 按照分配数据规则分
  • 1. 滚动窗口(Tumbling Windows)
  • 2. 滑动窗口(Sliding Windows)
  • 3. 会话窗口(Session Windows)
  • 4. 全局窗口(Global Windows)
  • 四、窗口API使用
  • 1. 按键分区(Keyed Windows)
  • 2.非按键分区
  • 3.窗口适配器( Window Assigners)
  • 1. 窗口适配器的区分和使用:
  • 3.窗口函数(ProcessWindowFunction)
  • 1. 数据流转换图
  • 2. 增量聚合函数(incremental aggregation functions)
  • 3. 全窗口函数(full window functions)
  • 1. 窗口函数(WindowFunction)
  • 2. 处理窗口函数(ProcessWindowFunction)
  • 4.窗口生命周期
  • 1. 窗口的创建
  • 2. 窗口计算的触发
  • 3. 窗口的销毁
  • 5.迟到数据的处理(重点)
  • 结束~

1. 事件时间(Event Time)

flink 时间窗口 编程_大数据

2. 处理时间(Processing Time)

处理时间是指数据真正被Flink处理的时间,是服务器时间

3. 摄入时间(Ingestion Time)

它是指数据进入 Flink 数据流的时间,也就是 Source 算子读入数据的时间。摄入时间相当于是事件时间和处理时间的一个中和,它是把 Source 任务的处理时间,当作了数据的产生时间添加到数据里。

1. 什么是水位线

本质就是时间戳,在流式环境下,我们通常用事件时间来进行统计分析,事件时间又不属于系统时间,因此我们怎么衡量时间的进展,就是通过水位线(Watermark)。

flink 时间窗口 编程_大数据_02

2. 水位线分类

1. 有序流中的水位线

flink 时间窗口 编程_Time_03

1、如何使用
2. 乱序流中的水位线

flink 时间窗口 编程_数据_04

2.1 乱序流中如何保证数据的准确性
2.2 如何使用

1. 什么是窗口

Flink是一种流式引擎,数据是源源不断到来的,但是我们统计周期往往是有界的,因此在处理数据的时候我们需要把源源不断的数据切分成有界的数据,这就是窗口。

在开发指标中有些定义如下:

  • 每分钟的浏览量
  • 每位用户每周的会话数
  • 每个传感器每分钟的最高温度

flink 时间窗口 编程_数据_05

flink 时间窗口 编程_flink 时间窗口 编程_06

2. 窗口分类

1. 按照驱动类型分
1. 计数窗口(Count Window)

计数窗口就是多少个数据为一个窗口,比如10个数据为一个窗口,那么这个窗口就会等凑到10个数据后再关闭,和时间无关。实际很少用。

2. 时间窗口(Time Window)

时间窗口是根据时间划分窗口的,Flink中基本都是使用时间窗口,因为我们在统计数据的时候一般都是以时间维度来进行统计的,如上面所属,每分钟、每小时、每天等。

1. 按照分配数据规则分

flink 时间窗口 编程_flink 时间窗口 编程_07

1. 滚动窗口(Tumbling Windows)

滚动窗口是按照固定的窗口大小设置的,对数据均匀切片,窗口之间不会重叠,也不会有间隔,每个窗口之间都是无缝衔接。比如:每分钟浏览量

flink 时间窗口 编程_大数据_08

如何使用:

2. 滑动窗口(Sliding Windows)

滑动窗口是在每个窗口之间有个滑动步长,滚动窗口就是滑动窗口的一种特例,当窗口大小等于滑动步长的时候就是滚动窗口,适合统计输出频率比较高的指标。比如:每10秒钟计算前1分钟的页面浏览量

flink 时间窗口 编程_flink_09

如何使用:

3. 会话窗口(Session Windows)

flink 时间窗口 编程_Time_10

如何使用:

4. 全局窗口(Global Windows)

flink 时间窗口 编程_Time_11

如何使用:

主要是对窗口API的使用说明

1. 按键分区(Keyed Windows)

按键分区是指对数据流进行keyby操作,数据流会按照key分为多个流,生成keyedStream,此时如果使用窗口函数,那么将会多所有key上进行,相同的key发送到同一个并行子任务,窗口基于每一个key进行单独处理,使用上需要使用keyby函数将数据流转换为keyedStream。

2.非按键分区

如果实际场景中不需要使用按键分区,则可以不适用按键分区,此时我们可以调用非按键分区的API,缺点是此时的窗口不是并行处理的。窗口逻辑只能在一个任务( task)上执行,就相当于并行度变成了 1。 不推荐使用。

flink 时间窗口 编程_数据_12

3.窗口适配器( Window Assigners)

flink 时间窗口 编程_大数据_13

1. 窗口适配器的区分和使用:
  1. 滚动时间窗口
  • 每分钟页面浏览量
  1. 滑动时间窗口
  • 每10秒钟计算前1分钟的页面浏览量
  1. 会话窗口
  • 每个会话的网页浏览量,其中会话之间的间隔至少为30分钟
  1. 无法正确处理历史数据,
  2. 无法正确处理超过最大无序边界的数据,
  3. 结果将是不确定的,

使用基于计数的窗口时,只有窗口内的事件数量到达窗口要求的数值时,这些窗口才会触发计算。尽管可以使用自定义触发器自己实现该行为,但无法应对超时和处理部分窗口。
我们可能在有些场景下,想使用全局 window assigner 将每个事件(相同的 key)都分配给某一个指定的全局窗口。 很多情况下,一个比较好的建议是使用 ProcessFunction。

3.窗口函数(ProcessWindowFunction)

1. 数据流转换图

flink 时间窗口 编程_大数据_14

2. 增量聚合函数(incremental aggregation functions)

这里对四个方法进行总结下:

  1. createAccumulator():创建一个累加器,这就是为聚合创建了一个初始状态,每个聚合任务只会调用一次。
  2. add():将输入的元素添加到累加器中。这就是基于聚合状态,对新来的数据进行进一步聚合的过程。方法传入两个参数:当前新到的数据 value,和当前的累加器accumulator;返回一个新的累加器值,也就是对聚合状态进行更新。每条数据到来之后都会调用这个方法。
  3. getResult():从累加器中提取聚合的输出结果。也就是说,我们可以定义多个状态,然后再基于这些聚合的状态计算出一个结果进行输出。比如之前我们提到的计算平均值,就可以把 sum 和 count 作为状态放入累加器,而在调用这个方法时相除得到最终结果。这个方法只在窗口要输出结果时调用。
  4. merge():合并两个累加器,并将合并后的状态作为一个累加器返回。这个方法只在需要合并窗口的场景下才会被调用;最常见的合并窗口(Merging Window)的场景就是会话窗口(Session Windows)。
3. 全窗口函数(full window functions)

与增量聚合函数不同,全窗口函数需要先收集窗口中的数据,并在内部缓存起来,等到窗口要输出结果的时候再取出数据进行计算。 思路就是攒批处理
在 Flink 中,全窗口函数也有两种: WindowFunction 和 ProcessWindowFunction。

1. 窗口函数(WindowFunction)

我们可以基于 WindowedStream 调用.apply()方法,传入一个 WindowFunction 的实现类。 这个类中可以获取到包含窗口所有数据的可迭代集合( Iterable),还可以拿到窗口(Window)本身的信息。 当窗口到达结束时间需要触发计算时,就会调用这里的 apply 方法。我们可以从 input 集合中取出窗口收集的数据,结合 key 和 window 信息,通过收集器(Collector)输出结果。这里 Collector 的用法,与 FlatMapFunction 中相同。已被ProcessWindowFunction替代

2. 处理窗口函数(ProcessWindowFunction)

除了可以拿到窗口中的所有数据之外, ProcessWindowFunction 还可以获取到一个“上下文对象”(Context)。这个上下文对象不仅能够获取窗口信息,还可以访问当前的时间和状态信息。这里的时间就包括了处理时间(processing time)和事件时间水位线( eventtime watermark)。这就使得 ProcessWindowFunction 更加灵活、功能更加丰富。事实上,ProcessWindowFunction 是 Flink 底层 API处理函数( process function)中的一员。ProcessWindowFunction 同样需要将所有数据缓存下来、等到窗口触发计算时才使用。它其实就是一个增强版的 WindowFunction。

4.窗口生命周期

1. 窗口的创建

窗口的类型是根据上面的窗口适配器确定的,但是窗口的实际创建是根据数据来确定的,也就是说服务器时间到了9:00:00 但是没有9:00:00的数据到来,那么9点整的窗口是不会创建的,只有9:00:00的这个窗口的数据到来了之后才会进行创建。

2. 窗口计算的触发
  1. 滚动事件时间窗口,应该在水位线到达窗口结束时间的时候触发计算。(如果设置了延时时间,但还没有到达设定的最大延迟时间,这期间内到达的迟到数据也会触发窗口计算 )
  2. 计数窗口,会在窗口中元素数量达到定义大小时触发计算 。
3. 窗口的销毁

一般情况下,当时间到达了结束点就会触发计算,然后输出计算结果并销毁窗口。但是Flink中只针对时间窗口有销毁机制,计数窗口是基于全局窗口实现的,全局窗口不会清除状态,因此不会被销毁。

5.迟到数据的处理(重点)

在Flink中我们即使定义了水位线的延迟策略,那么也不能保证数据全部都能及时被统计,Flink为了保证数据的最终一致性,采用了侧输出流的机制将迟到的数据收集到侧输出流中:

我们还可以指定 允许的延迟(allowed lateness) 的间隔,在这个间隔时间内,延迟的事件将会继续分配给窗口(同时状态会被保留),默认状态下,每个延迟事件都会导致窗口函数被再次调用(有时也称之为 late firing )。
默认情况下,允许的延迟为 0。换句话说,watermark 之后的元素将被丢弃(或发送到侧输出流)
举例说明:




当允许的延迟大于零时,只有那些超过最大无序边界以至于会被丢弃的事件才会被发送到侧输出流(如果已配置)。

到此这篇窗口函数 聚合函数(窗口函数原理)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 指数与对数的转换公式图(指数与对数的转换公式图解)2025-07-29 13:09:10
  • 暂无可用支付方式是什么意思(暂无可用支付方式,不能使用付款)2025-07-29 13:09:10
  • 指数与对数的运算法则(指数对数的运算法则及公式)2025-07-29 13:09:10
  • sigmoid 计算(sigmoid计算降雨公式)2025-07-29 13:09:10
  • 泰拉瑞亚时间指令格式(泰拉瑞亚怎么调时间指令)2025-07-29 13:09:10
  • ip报文格式中如果首部长度为52(ip报文首部长度最大为)2025-07-29 13:09:10
  • redis 哨兵模式配置(redis 哨兵模式配置方式)2025-07-29 13:09:10
  • privot函数(preorder函数)2025-07-29 13:09:10
  • 支付方式英文(宽松的支付方式英文)2025-07-29 13:09:10
  • 编程入门应该学什么专业(编程基础入门要学什么)2025-07-29 13:09:10
  • 全屏图片