之前的四篇文章对Flink常用的算子进行了详细讲解并附上了大量使用案例:
- Flink单数据流基本转换:map、filter、flatMap
- Flink基于Key的分组转换:keyBy、reduce和aggregations
- Flink多数据流转换:union和connect
- Flink并行度和数据重分配
总结下来不难发现,使用Flink的算子必须进行自定义,自定义时可以使用Lambda表达式,也可以继承并重写函数类。本文将带大家阅读一些Flink源码,并提供具体的算子使用例子。
函数类
对于map
、flatMap
、reduce
等方法,我们可以实现MapFunction
、FlatMapFunction
、ReduceFunction
等interface接口。这些函数类签名中都有泛型参数,用来定义该函数的输入或输出的数据类型。我们要继承这些类,并重写里面的自定义函数。以flatMap
对应的FlatMapFunction
为例,它在源码中的定义为:
public interface FlatMapFunction<T, O> extends Function, Serializable {
void flatMap(T value, Collector<O> out) throws Exception;
}
这是一个接口类,它继承了Flink的Function
函数式接口。函数式接口只有一个抽象函数方法(Single Abstract Method),其目的是为了方便Java 8 Lambda表达式的使用。此外,它还继承了Serializable
,以便进行序列化,这是因为这些函数在运行过程中要发送到各个TaskManager上,发送前后要进行序列化和反序列化。需要注意的是,使用这些函数时,一定要保证函数内的所有内容都可以被序列化。如果有一些不能被序列化的内容,或者使用接下来介绍的Rich函数类,或者重写Java的序列化和反序列化方法。</