注:本文源码为flink 1.18.0版本。
其他相关文章:
Flink window 源码分析1:窗口整体执行流程
Flink window 源码分析2:Window 的主要组件
Flink window 源码分析3:WindowOperator
Flink window 源码分析4:WindowState
1 window 的重要组件
Window 本质上就是借助状态后端缓存着一定时间段内的数据,然后在达到某些条件时触发对这些缓存数据的聚合计算,输出外部系统。
其主要组件有:Window Assigners、Triggers、Evictors。这三个组件的详细讲解请看笔记:Flink window 源码分析2:Window 的主要组件。
- Window Assigners
Window assigner 定义了 stream 中的元素如何被分发到各个窗口。
Time Window 会创建一个 EventTimeTrigger 用来制定窗口触发时间。Count Window 和 GlobalWindow需要指定窗口触发器。
可以通过继承 WindowAssigner 抽象类实现自定义。 - Triggers
决定窗口是否触发。
Trigger 接口中有些主要的方法:onElement、onEventTime、onProcessingTime。
- Evictors(可选择是否指定)
在 trigger 触发后、调用窗口函数之前或之后从窗口中删除元素。
指定 evictors 可以避免预聚合(pre-aggregation),因为窗口内所有元素必须在应用计算之前传递给 evictors。
Flink 不保证窗口内元素的顺序。这意味着虽然 evictors 可以从窗口的开头移除元素,但这些元素不一定是先到的还是后到的。
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 定义为:文章来源:https://www.toymoban.com/news/detail-793899.html
private final WindowOperatorBuilder<T, K, W> builder;
进一步观察 builder.reduce(),看到其最终返回是 WindowOperator。在函数返回时会判断evictor是否为空,走不同的构造 WindowOperator 的逻辑,如果 evictor 不为空就构造 EvictingWindowOperator 对象,否则就构造 WindowOperator 对象,其实 EvictingWindowOperator 是 WindowOperator 的一个子类,只是多了一个删除数据的逻辑。WindowOperator 在创建时会传入一个 StateDescriptor 用于创建状态,存储中间结果或元素。
WindowOperator 的具体分析见:WindowOperator 的分析笔记。文章来源地址https://www.toymoban.com/news/detail-793899.html
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));
}
}
到了这里,关于Flink window 源码分析1:窗口整体执行流程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!