flink版本号1.18.1
public class WordCount {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> DataStreamSource = env.readTextFile("word.text");
SingleOutputStreamOperator<Tuple2<String, Long>> wordAndOne = DataStreamSource.flatMap(new FlatMapFunction<String, Tuple2<String, Long>>() {
@Override
public void flatMap(String value, Collector<Tuple2<String, Long>> out) throws Exception {
String[] words = value.split(" ");
for (String word : words) {
out.collect(Tuple2.of(word, 1L));
}
}
});
wordAndOne.keyBy(data -> data.f0).sum(1).print();
env.execute();
}
}
public class DataStream<T> {
protected final StreamExecutionEnvironment environment;
protected final Transformation<T> transformation;
/**
* Create a new {@link DataStream} in the given execution environment with partitioning set to
* forward by default.
*
* @param environment The StreamExecutionEnvironment
*/
public DataStream(StreamExecutionEnvironment environment, Transformation<T> transformation) {
this.environment =
Preconditions.checkNotNull(environment, "Execution Environment must not be null.");
this.transformation =
Preconditions.checkNotNull(
transformation, "Stream Transformation must not be null.");
}
}
每个StreamTransformation都包含相应的StreamOperator,例如执行DataStream.flatMap(new FlatMapFuction(…)) 转换之后,内部生成了StreamFlatMap,StreamOperator包含了自定义函数的信息,StreamFlatMap算子包含了FlatMapFuction。
以DataStream的flatMap转换操作为例,分析DataStream底层源码实现,首先自定义FlatMapFunction实现数据的处理逻辑,然后调用DataStream.flatMap()方法将FlatMapFunction作为参数应用在FlatMap转换操作中。在DataStream.flatMap()方法中可以看出,调用了transform()方法进行后续的转换处理,调用过程基于FlatMapFunction参数创建StreamFlatMap实例,StreamFlatMap本质上就是StreamOperator的实现类。
public <R> SingleOutputStreamOperator<R> flatMap(FlatMapFunction<T, R> flatMapper) {
TypeInformation<R> outType =
TypeExtractor.getFlatMapReturnTypes(
clean(flatMapper), getType(), Utils.getCallLocationName(), true);
return flatMap(flatMapper, outType);
}
public <R> SingleOutputStreamOperator<R> flatMap(
FlatMapFunction<T, R> flatMapper, TypeInformation<R> outputType) {
return transform("Flat Map", outputType, new StreamFlatMap<>(clean(flatMapper)));
}
public <R> SingleOutputStreamOperator<R> transform(
String operatorName,
TypeInformation<R> outTypeInfo,
OneInputStreamOperator<T, R> operator) {
return doTransform(operatorName, outTypeInfo, SimpleOperatorFactory.of(operator));
}
protected <R> SingleOutputStreamOperator<R> doTransform(
String operatorName,
TypeInformation<R> outTypeInfo,
StreamOperatorFactory<R> operatorFactory) {
// 获取上一次转换操作输出的TypeInformation信息
transformation.getOutputType();
// 基于operatorName、、outTypeInfo和operatorFactory等参数创建OneInputTransformation实例,其中OneInputTransformation会包含当前DataStream对应的上一次转换操作。
OneInputTransformation<T, R> resultTransform =
new OneInputTransformation<>(
this.transformation,
operatorName,
operatorFactory,
outTypeInfo,
environment.getParallelism(),
false);
// 基于resultTransform创建SingleOutputStreamOperator。SingleOutputStreamOperator继承自DataStream,每次转换操作返回给用户的数据结构,以便继续调用
@SuppressWarnings({"unchecked", "rawtypes"})
SingleOutputStreamOperator<R> returnStream =
new SingleOutputStreamOperator(environment, resultTransform);
// 将创建好的OneInputTransformation添加到env中的List>集合中,用于生成StreamGraph对象
getExecutionEnvironment().addOperator(resultTransform);
return returnStream;
}
在DataStream转换的过程中,不管是哪种类型的转换操作,都是按照相同的方式:首先将用户自定义的函数封装到Operator中,然后将Operator封装到Transformation转换操作中,最后将Transformation添加到StreamExecutionEnviroment提供的Transfromation集合。通过DataStream之间的转换操作生成pipeline即Streamgraph