flink window原理(Flink Window基本概念与实现原理)
Windo意为窗口。在流处理系统中数据源源不断流入到系统,我们可以逐条处理流入的数据,也可以按一定规则一次处理流中的多条数据。当处理数据时程序需要知道什么时候开始处理、处理哪些数据。窗口提供了这样一种依据,决定了数据何时开始处理。
Flink内置Windo
Flink有3个内置Windo
- 以事件数量驱动的Count Windo
- 以会话间隔驱动的Session Windo
- 以时间驱动的Time Windo
本文围绕这3个内置窗口展开讨论,我们了解这3个窗口在运行时产生的现象,再讨论它们的实现原理。
Count Windo
计数窗口,采用事件数量作为窗口处理依据。计数窗口分为滚动和滑动两类,使用keyedStream.countWindo实现计数窗口定义。
- Tumbling Count Windo 滚动计数窗口
- 例子以用户分组,当每位用户有3次付款事件时计算一次该用户付款总金额。下图中“消息A、B、C、D”代表4位不同用户,我们以A、B、C、D分组并计算金额。
- Sliding Count Windo 滑动计数窗口
- 例子一位用户每3次付款事件计算最近4次付款事件总金额。
Session Windo
会话窗口,采用会话持续时长作为窗口处理依据。设置指定的会话持续时长时间,在这段时间中不再出现会话则认为超出会话时长。
例子每只股票超过2秒没有交易事件时计算窗口内交易总金额。下图中“消息A、消息B”代表两只不同的股票。
/ 会话持续2秒。当超过2秒不再出现会话认为会话结束 / keyedStream.indo(ProcessingTimeSessionWindos.ithGap(Time.seconds(2)))Time Windo
时间窗口,采用时间作为窗口处理依据。时间窗分为滚动和滑动两类,使用keyedStream.timeWindo实现时间窗定义。
- Tumbling Time Windo 滚动时间窗口
- Sliding Time Windo 滑动时间窗口
Flink Windo组件
Flink Windo使用3个组件协同实现了内置的3个窗口。通过对这3个组件不同的组合,可以满足许多场景的窗口定义。
WindoAssigner组件为数据分配窗口、Trigger组件决定如何处理窗口中的数据、借助Evictor组件实现灵活清理窗口中数据时机。
WindoAssigner
当有数据流入到Windo Operator时需要按照一定规则将数据分配给窗口,WindoAssigner为数据分配窗口。下面代码片段是WindoAssigner部分定义,assignWindos方法定义返回的结果是一个集合,也就是说数据允许被分配到多个窗口中。
/ WindoAssigner关键接口定义 / public abstract class WindoAssignerFlink内置WindoAssigner
Flink针对不同窗口类型实现了相应的WindoAssigner。Flink 1.7.0继承关系如下图
Trigger
Trigger触发器,它定义了3个触发动作,并且定义了触发动作处理完毕后的返回结果。返回结果交给Windo Operator后由Windo Operator决定后续操作。也就是说,Trigger通过具体的动作处理结果决定窗口是否应该被处理、被清除、被处理+清除、还是什么都不做。
/ Trigger关键接口定义 / public abstract class Trigger当有数据流入Windo Operator时会触发onElement方法、当处理时间和事件时间生效时会触发onProcessingTime和onEventTime方法。每个触发动作的返回结果用TriggerResult定义。
TriggerResult返回类型及说明
Trigger触发运算后返回处理结果,处理结果使用TriggerResult枚举表示。
public enum TriggerResult { CONTINUE,FIRE,PURGE,FIRE_AND_PURGE; }Flink内置Trigger
Flink的内置窗口(Counter、Session、Time)有自己的触发器实现。下表为不同窗口使用的触发器。
Evictor
Evictor驱逐者,如果定义了Evictor当执行窗口处理前会删除窗口内指定数据再交给窗口处理,或等窗口执行处理后再删除窗口中指定数据。
public interface EvictorFlink内置Evictor
实现原理
通过KeyedStream可以直接创建Count Windo和Time Windo。他们最终都是基于indo(WindoAssigner)方法创建,在indo方法中创建WindoedStream实例,参数使用当前的KeyedStream对象和指定的WindoAssigner。
/ 依据WindoAssigner实例化WindoedStream / public构造器执行完毕后,WindoedStream创建完成。构造器中初始化了3个属性。默认情况下trigger属性使用WindoAssigner提供的DefaultTrigger作为初始值。
,WindoedStream提供了trigger方法用来覆盖默认的trigger。Flink内置的计数窗口就使用indoedStream.trigger方法覆盖了默认的trigger。
public WindoedStream在WindoedStream中还有一个比较重要的属性evictor,可以通过evictor方法设置。
public WindoedStreamWindoedStream实现中根据evictor属性是否空(null == evictor)决定是创建WindoOperator还是EvictingWindoOperator。EvictingWindoOperator继承自WindoOperator,它主要扩展了evictor属性以及相关的逻辑处理。
public class EvictingWindoOperator extends WindoOperator { private final Evictor evictor; }Evictor定义了清理数据的时机。在EvictingWindoOperator的emitWindoContents方法中,实现了清理数据逻辑调用。这也是EvictingWindoOperator与WindoOperator的主要区别。「在WindoOperator中压根就没有evictor的概念」
private void emitWindoContents(W indo, IterableCount Windo API
下面代码片段是KeyedStream提供创建Count Windo的API。
/ 滚动计数窗口 / public WindoedStream滚动计数窗口与滑动计数窗口有几个差异
- 入参不同
- 滑动窗口使用了evictor组件
- 两者使用的trigger组件不同
下面我们对这几点差异做深入分析,看一看他们是如何影响滚动计数窗口和滑动计数窗口的。
Count Windo Assigner
通过方法indo(GlobalWindos.create())创建WindoedStream实例,滚动计数窗口处理和滑动计数窗口处理都是基于GlobalWindos作为WindoAssigner来创建窗口处理器。GlobalWindos将所有数据都分配到同一个GlobalWindo中。「这里需要注意GlobalWindos是一个WindoAssigner,而GlobalWindo是一个Windo」
/ GlobalWindos是一个WindoAssigner实现,这里只展示实现assignWindos的代码片段 / public class GlobalWindos extends WindoAssigner免费软件
- 泰安热水器厂家维修(泰安热水器常见故障及解
- 克来沃空调售后服务电话 ——售后维修中心电话
- 襄阳冰箱24小时服务热线-全国统一人工【7X24小时
- 乐清热水器故障维修(全国联保服务)各网点-24小时
- 温州空调售后维修服务中心-24小时服务热线
- 长沙嘉善燃气灶售后维修服务中心-(7X24小时)登
- 鄢陵市清远(HISENSE)壁挂炉全国服务电话-厂家维修
- 石家庄德州壁挂炉售后维修服务中心-全国统一人
- 克来沃空调售后维修服务电话号码-全国统一服务
- 新余空调不制冷不制热缺氟缺冷媒怎么办?空调
- 温州宿州壁挂炉售后维修服务中心
- 台山空调售后服务号码-24小时服务热线
- 阳江冰箱客户服务电话-(7X24小时)登记报修热线
- 铜川冰箱不制冷原因分析
- 用食用碱清洗油烟机的方法(用食用盐清洗厨房油
- 遵义热水器维修热线-全国统一客户服务中心