虚拟化技术原理与实现 pdf_技术专栏丨Flink Window基本概念与实现原理

本文深入探讨Flink中的内置窗口——Count Window、Session Window和Time Window,详细阐述它们的工作原理和使用场景。通过WindowAssigner、Trigger和Evictor组件的组合,Flink实现了强大的窗口功能,支持数据流处理中的多种窗口操作,如滚动、滑动和会话窗口。
摘要由CSDN通过智能技术生成

Window意为窗口。在流处理系统中数据源源不断流入到系统,我们可以逐条处理流入的数据,也可以按一定规则一次处理流中的多条数据。当处理数据时程序需要知道什么时候开始处理、处理哪些数据。窗口提供了这样一种依据,决定了数据何时开始处理。

Flink内置Window

Flink有3个内置Window

  • 以事件数量驱动的Count Window

  • 以会话间隔驱动的Session Window

  • 以时间驱动的Time Window

本文围绕这3个内置窗口展开讨论,我们首先了解这3个窗口在运行时产生的现象,最后再讨论它们的实现原理。

Count Window

计数窗口,采用事件数量作为窗口处理依据。计数窗口分为滚动和滑动两类,使用keyedStream.countWindow实现计数窗口定义。

  • Tumbling Count Window 滚动计数窗口例子:以用户分组,当每位用户有3次付款事件时计算一次该用户付款总金额。下图中“消息A、B、C、D”代表4位不同用户,我们以A、B、C、D分组并计算金额。

/** 每3个事件,计算窗口内数据 */
keyedStream.countWindow(3);
5aff4cab7e29d5f516a65aba76b7400d.png
  • Sliding Count Window 滑动计数窗口例子:一位用户每3次付款事件计算最近4次付款事件总金额。

/** 每3个事件,计算最近4个事件消息 */
keyedStream.countWindow(4,3);

7660e2e1d652f5c134a21d8b620cbad0.png

Session Window

会话窗口,采用会话持续时长作为窗口处理依据。设置指定的会话持续时长时间,在这段时间中不再出现会话则认为超出会话时长。

例子:每只股票超过2秒没有交易事件时计算窗口内交易总金额。下图中“消息A、消息B”代表两只不同的股票。

/** 会话持续2秒。当超过2秒不再出现会话认为会话结束 */
keyedStream.window(ProcessingTimeSessionWindows.withGap(Time.seconds(2)))
e2f654f0266c2e4e0c30027eb1ce9f13.png

Time Window

时间窗口,采用时间作为窗口处理依据。时间窗分为滚动和滑动两类,使用keyedStream.timeWindow实现时间窗定义。

  • Tumbling Time Window 滚动时间窗口:

/** 每1分钟,计算窗口数据 */
keyedStream.timeWindow(Time.minutes(1));
537a1970ae0a57918db5591bdf776692.png
  • Sliding Time Window 滑动时间窗口:

/** 每半分钟,计算最近1分钟窗口数据 */
keyedStream.timeWindow(Time.minutes(1), Time.seconds(30));
e2db9b26dc675b54942a97c3e1d1d24f.png

Flink Window组件

Flink Window使用3个组件协同实现了内置的3个窗口。通过对这3个组件不同的组合,可以满足许多场景的窗口定义。


WindowAssigner组件为数据分配窗口、Trigger组件决定如何处理窗口中的数据、借助Evictor组件实现灵活清理窗口中数据时机。

WindowAssigner

当有数据流入到Window Operator时需要按照一定规则将数据分配给窗口,WindowAssigner为数据分配窗口。下面代码片段是WindowAssigner部分定义,assignWindows方法定义返回的结果是一个集合,也就是说数据允许被分配到多个窗口中。

/*** WindowAssigner关键接口定义 ***/
public abstract class WindowAssigner<T, W extends Window> implements Serializable {

    /** 分配数据到窗口集合并返回 */
    public abstract Collection assignWindows(T element, long timestamp, WindowAssignerContext context);
}
Flink内置WindowAssigner

Flink针对不同窗口类型实现了相应的WindowAssigner。Flink 1.7.0继承关系如下图

d1d462dadf8f29382668109243654995.png efe0b69bc03ca6819562fe179a9890d8.png

Trigger

Trigger触发器,它定义了3个触发动作,并且定义了触发动作处理完毕后的返回结果。返回结果交给Window Operator后由Window Operator决定后续操作。也就是说,Trigger通过具体的动作处理结果决定窗口是否应该被处理、被清除、被处理+清除、还是什么都不做。
/** Trigger关键接口定义 */
public abstract class Trigger<T, W extends Window> implements Serializable {

    /*** 新的数据进入窗口时触发 ***/
    public abstract TriggerResult onElement(T element, long timestamp, W window, TriggerContext ctx) throws Exception;

    /*** 处理时间计数器触发 ***/
    public abstract TriggerResult onProcessingTime(long time, W window, TriggerContext ctx) throws Exception;

    /*** 事件时间计数器触发 ***/
    public abstract TriggerResult onEventTime(long time, W window, TriggerContext ctx) throws Exception;
}

当有数据流入Window Operator时会触发onElement方法、当处理时间和事件时间生效时会触发onProcessingTime和onEventTime方法。每个触发动作的返回结果用TriggerResult定义。

TriggerResult返回类型及说明

Trigger触发运算后返回处理结果,处理结果使用TriggerResult枚举表示。

public enum TriggerResult {
    
    CONTINUE,FIRE,PURGE,FIRE_AND_PURGE;
}
40433e3c03ce9c7ba3fd10b51b7fb700.png Flink内置Trigger

Flink的内置窗口(Counter、Session、Time)有自己的触发器实现。下表为不同窗口使用的触发器。

c6f7b7bbe821673c40a13ded4ad0a32e.png

Evictor

Evictor驱逐者,如果定义了Evictor当执行窗口处理前会删除窗口内指定数据再交给窗口处理,或等窗口执行处理后再删除窗口中指定数据。

public interface Evictor<T, W extends Window> extends Serializable {
    
    /** 在窗口处理前删除数据 */
    void evictBefore(Iterable> elements, int size, W window, EvictorContext evictorContext);/** 在窗口处理后删除数据 */void evictAfter(Iterable> elements, int size, W window, EvictorContext evictorCon
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值