Flink window 源码分析1:窗口整体执行流程

Flink window 源码分析1:窗口整体执行流程
Flink window 源码分析2:Window 的主要组件
Flink window 源码分析3:WindowOperator
Flink window 源码分析4:WindowState
本文分析的源码为flink 1.18.0_scala2.12版本。

1 window 的重要组件

Window 本质上就是借助状态后端缓存着一定时间段内的数据,然后在达到某些条件时触发对这些缓存数据的聚合计算,输出外部系统。
window 的元素处理主要流程.png
其主要组件有:Window Assigners、Triggers、Evictors。这三个组件的详细讲解请看笔记:Flink window 源码分析2:Window 的主要组件

  1. Window Assigners
    Window assigner 定义了 stream 中的元素如何被分发到各个窗口。
    Time Window 会创建一个 EventTimeTrigger 用来制定窗口触发时间。Count Window 和 GlobalWindow需要指定窗口触发器。
    可以通过继承 WindowAssigner 抽象类实现自定义。
  2. Triggers
    决定窗口是否触发。
    Trigger 接口中有些主要的方法:onElement、onEventTime、onProcessingTime。
    系统提供的 Triggers.png
  3. Evictors(可选择是否指定)
    在 trigger 触发后、调用窗口函数之前或之后从窗口中删除元素。
    指定 evictors 可以避免预聚合(pre-aggregation),因为窗口内所有元素必须在应用计算之前传递给 evictors。
    Flink 不保证窗口内元素的顺序。这意味着虽然 evictors 可以从窗口的开头移除元素,但这些元素不一定是先到的还是后到的。
    系统提供的 evictors.png

2 window 的触发过程

KeyedStream 调用 window 函数会生成 WindowStream。WindowedStream 可以调用 reduce、aggregate、apply、process 等函数。 以下是 window 函数使用示例。

source.keyBy((KeySelector<Tuple2<Long, String>, String>) value -> value.f2)  
.window(TumblingEventTimeWindows.of(Time.seconds(60)))  
.apply(...);

window 函数源码如下。返回了一个 WindowedStream。

@PublicEvolving  
public <W extends Window> WindowedStream<T, KEY, W> window(  
        WindowAssigner<? super T, W> assigner) {  
    return new WindowedStream<>(this, assigner);  
}

观察 reduce、aggregate、apply、process 等处理函数,会看到会进一步调用属性 builder 的对应的 reduce、aggregate、apply、process 方法。以 reduce 源码为例,可以看到倒数第2行 builder.reduce。

@Internal  
public <R> SingleOutputStreamOperator<R> reduce(  
        ReduceFunction<T> reduceFunction,  
        ProcessWindowFunction<T, R, K, W> function,  
        TypeInformation<R> resultType) {  
    // clean the closures  
    function = input.getExecutionEnvironment().clean(function);  
    reduceFunction = input.getExecutionEnvironment().clean(reduceFunction);  
  
    final String opName = builder.generateOperatorName();  
    final String opDescription = builder.generateOperatorDescription(reduceFunction, function);  
    OneInputStreamOperator<T, R> operator = builder.reduce(reduceFunction, function);  
  
    return input.transform(opName, resultType, operator).setDescription(opDescription);  
}

builder 是 WindowOperatorBuilder,在 WindowedStream 的构造函数中有其初始化。builder 定义为:

private final WindowOperatorBuilder<T, K, W> builder;

进一步观察 builder.reduce(),看到其最终返回是 WindowOperator。在函数返回时会判断evictor是否为空,走不同的构造 WindowOperator 的逻辑,如果 evictor 不为空就构造 EvictingWindowOperator 对象,否则就构造 WindowOperator 对象,其实 EvictingWindowOperator 是 WindowOperator 的一个子类,只是多了一个删除数据的逻辑。WindowOperator 在创建时会传入一个 StateDescriptor 用于创建状态,存储中间结果或元素。
WindowOperator 的具体分析见:WindowOperator 的分析笔记

public <R> WindowOperator<K, T, ?, R, W> reduce(  
        ReduceFunction<T> reduceFunction, WindowFunction<T, R, K, W> function) {  
    Preconditions.checkNotNull(reduceFunction, "ReduceFunction cannot be null");  
    Preconditions.checkNotNull(function, "WindowFunction cannot be null");  
  
    if (reduceFunction instanceof RichFunction) {  
        throw new UnsupportedOperationException(  
                "ReduceFunction of apply can not be a RichFunction.");  
    }  
  
    if (evictor != null) {  
        return buildEvictingWindowOperator(  
                new InternalIterableWindowFunction<>(  
                        new ReduceApplyWindowFunction<>(reduceFunction, function)));  
    } else {  
        ReducingStateDescriptor<T> stateDesc =  
                new ReducingStateDescriptor<>(  
                        WINDOW_STATE_NAME, reduceFunction, inputType.createSerializer(config));  
  
        return buildWindowOperator(  
                stateDesc, new InternalSingleValueWindowFunction<>(function));  
    }  
}
  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值