这里包含Graph的处理,最终生成物理执行图,以及Slot到发布Task到TaskExecutor上运行。如下所示:
- Flink编程套路总结
- Flink提交执行脚本分析
- Flink CliFronted提交应用程序源码剖析
- ExecutionEnvironment源码解析
- Job提交流程源码分析
- StreamGraph构建和提交源码解析
- JobGragh构建和提交源码解析
- ExecutionGragh构建和提交源码解析
- Slot管理(申请)源码解析
- Task提交到TaskExecutor执行源码剖析
1、Flink Program编程套路总结
Flink底层提供了一个功能完善且复杂的分布式流式计算引擎,但是上层的应用API却很简单,简单来说,把整个Flink应用程序的编写,抽象成三个方面:
- 执行环境 ExectionEnvironment
- 数据抽象 DataSet DataStream
- 逻辑操作 Source Transformation Sink
所以Flink的应用程序在编写的时候,基本是一个简单的统一套路:
1、获取执行环境对象
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
2、通过执行环境对象,注册数据源Source,得到数据抽象
DataStream ds = env.socketTextStream(...)
3、调用数据抽象的各种Transformation执行逻辑计算
DataStream resultDS = ds.flatMap(...).keyBy(...).sum(...);
4、将各种Transformation执行完毕之后得到的计算结果数据抽象注册 Sink
resultDS.addSink(...)
5、提交Job执行
env.execute(...)
在Flink应用程序中,其实所有的操作,都是StreamOperator,分为SourceOperator,SinkOperator,StreamOperator,然后能被优化的Operator就会chain在一起,形成一个OperatorChain。
基本路数,和Spark一致,并且,在Flink-1.12版本中,DataStream已经具备高效批处理操作处理了。更加做到了流批处理的统一(API统一)。据"Flink Forward Asia 2020 在线峰会"阿里流式计算负责人王峰介绍:在Flink-1.13版本,将会完全统一流批处理的API。
2、Flink Job提交脚本解析
当编写好Flink的应用程序,正常的提交方式为:打成jar包,通过flink命令来进行提交。
flink run xxx.jar class arg1 arg2
flink命令脚本的底层,是通过java命令启动:CliFrontend类来启动JVM进程执行任务的构造和提交:
# 注释 去提交一个jar到Flink集群运行
# 会到CliFrontend的main方法提交任务
# Add HADOOP_CLASSPATH to allow the usage of Hadoop file systems
exec $JAVA_RUN $JVM_ARGS $FLINK_ENV_JAVA_OPTS "${log_setting[@]}" -classpath "`manglePathList "$CC_CLASSPATH:$INTERNAL_HADOOP_CLASSPATHS"`" org.apache.flink.client.cli.CliFrontend "$@"
3、Flink CliFronted提交应用程序源码剖析
找到CliFrontend的main方法,来执行任务的提交,核心代码如下:
/*****************************************
* TODO
* 注释: 初始化 CliFrontend
*/
final CliFrontend cli = new CliFrontend(configuration, customCommandLines);
/*************************************************
* TODO
* 注释: 运行
* 解析命令行并并开始请求操作
*
* flink run class arg1
* args[0] = run
*/
int retCode = SecurityUtils.getInstalledContext().runSecured(() -> cli.parseParameters(args));
System.exit(retCode);
进入到parseParameters(String[] args)方法,由于第一个参数为run,会进入到run(String[] args)方法。会做以下事情,包括解析jar包,找到主类以及依赖,然后通过反射的方式提交任务。
/*************************************************
* TODO 注释: 构建 Program 打包好了的程序,要去解析jar包,找到主类以及依赖。
*
*/
final PackagedProgram program = getPackagedProgram(programOptions);
// TODO 注释: 依赖jar处理
final List<URL> jobJars = program.getJobJarAndDependencies();
/*************************************************
* TODO
* 注释: 有效配置
* 1、activeCommandLine
* 2、commandLine
* 3、programOptions 程序参数
* 4、jobJars 依赖jar
*/
final Configuration effectiveConfiguration = getEffectiveConfiguration(activeCommandLine, commandLine, programOptions, jobJars);
/*************************************************
* TODO
* 注释:把任务提交执行
*/
executeProgram(effectiveConfiguration, program);
最终是在PackagedProgram.callMainMethod(...)方法中通过mainMethod.invoke(null, (Object) args);来跳转到运行主类的 main 方法。
总结如下:
当用户把Flink应用程序打成jar使用flink run ... 的shell命令提交的时候,底层是通过CliFrontend来处理。底层的逻辑,就是通过反射来调用用户程序的 main() 方法执行。
在刚组建内部,主要有以下几件事要做:
1、根据 flink 后面的执行命令来确定执行方法(run ==> run(params))
2、解析 main 参数,构建 PackagedProgram,然后执行 PackagedProgram
3、通过反射获取应用程序的 main 方法的实例,通过反射调用执行起来
总的来说,就是准备执行Program所需要的配置,jar包,运行主类等的必要的信息,然后提交执行。
4、ExecutionEnvironment源码解析
Flink应用程序的执行,首先就是创建运行环境StreamExecutionEnvironment,一般在企业环境中,都是通过getExecutionEnvironment()来获取ExecutionEnvironment,如果是本地运行的话,则会获取到:LocalStreamEnvironment,如果是提交到Flink集群运行,则获取到:StreamExecutionEnvironment。
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
&n

本文深入解析Flink的编程模型与执行流程,从获取执行环境、构建和提交StreamGraph,到JobGraph的生成、Slot管理和TaskExecutor执行。通过Flink的源码分析,展示了从FlinkProgram到物理执行图的转变过程,以及任务提交到Flink集群的详细步骤,阐述了Flink如何构建高效并行的DAG执行图。
最低0.47元/天 解锁文章
411

被折叠的 条评论
为什么被折叠?



