FlinkX启动流程分析

base FlinkX源码1.12_release版本

flinkX启动主要依赖两部分:

flink-client
它主要完成解析用户的提交指令,完成作业提交

flink-dist

这部分是打包后的target,包含了各个异构数据源的connector,和关键的flinkx-core

启动脚本:flinx/bin/flinkx

A.提交过程:

入口类:com.dtstack.flinkx.client.Launcher

从main方法开始:

1.通过OptionParser类解析校验启动时传入的参数

OptionParser optionParser = new OptionParser(args);
Options launcherOptions = optionParser.getOptions();

2.从配置中读取flink_dist目录位置,如果配置中没有,就从环境变量中获取

findDefaultConfigDir(launcherOptions);

3.如果不是local模式启动,还需要读取flink配置和hadoop配置位置(优先参数,其次环境变量)
4.将参数List转换为Map,方便get
5.获取参数中-p的内容,将其替换到-job中(这个-p配置是k=v,k=v,k=v形式,此处会替换掉-job配置中的${k}内容)

String s = temp.get("-p");
if (StringUtils.isNotBlank(s)) {
     HashMap<String, String> parameter = JsonModifyUtil.CommandTransform(s);
     temp.put("-job", JsonModifyUtil.JsonValueReplace(temp.get("-job"), parameter));
 }

6.创建JobDeployer对象,这里边主要就是各种处理后的配置信息

JobDeployer jobDeployer = new JobDeployer(launcherOptions, argList);

7.通过判断启动参数中的启动模式,创建ClusterClientHelper对象,不同模式submit任务的方式有差异
例如:
local模式:这个没什么好说的,直接执行Main

String[] args = jobDeployer.getProgramArgs().toArray(new String[0]);
Main.main(args);

yarn-session模式:这个机制和原生flink一样,维持一个flink集群在yarn上,每次向这个集群提交job,细节如下:
a.启动参数,yarn,hadoop配置获取

Options launcherOptions = jobDeployer.getLauncherOptions();
List<String> programArgs = jobDeployer.getProgramArgs();
Configuration flinkConfig = launcherOptions.loadFlinkConfiguration();
String yarnConfDir = launcherOptions.getHadoopConfDir();

b.初始化yarn客户端

YarnClient yarnClient = YarnClient.createYarnClient()

c.获取当前flink集群的applicationId,按需调整内存和cpu配置

applicationId = getAppIdFromYarn(yarnClient, flinkConfig);

d.配置高可用信息
e.初始化YarnClusterDescriptor
f.生成jobGraph,提交作业,拿到ClusterClient

ClusterClient clusterClient =
      yarnClusterDescriptor.retrieve(applicationId).getClusterClient();
JobGraph jobGraph =
      JobGraphUtil.buildJobGraph(launcherOptions, programArgs.toArray(new String[0]));
JobID jobID = (JobID) clusterClient.submitJob(jobGraph).get();

yarn-PerJob模式:这个就是直接读取配置提交yarn 任务了,最后也是拿到一个ClusterClient

8.至此完成任务提交,不同模式提交后(local, yarn-perJob,yarn-session,k8s等),真正执行任务的是flink-core中的Main

B.执行过程:

flink-core中

入口类:com.dtstack.flinkx.Main

1.读取各种参数

Options options = new OptionParser(args).getOptions();
String job = URLDecoder.decode(options.getJob(), Charsets.UTF_8.name());
Properties confProperties = PropertiesUtil.parseConf(options.getConfProp());

2.创建flink StreamExecutionEnvironment StreamTableEnvironment

StreamExecutionEnvironment env = EnvFactory.createStreamExecutionEnvironment(options);
StreamTableEnvironment tEnv =
     EnvFactory.createStreamTableEnvironment(env, confProperties, options.getJobName());

3.根据参数中的作业类型判断是sql任务还是同步任务。

 case SQL:
        exeSqlJob(env, tEnv, job, options);
 break;
 case SYNC:
        exeSyncJob(env, tEnv, job, options);
 break;

这里先看同步任务:

4.检查同步任务需要的各种配置,source & sink & metric 插件的路径

 configStreamExecutionEnvironment(env, options, config);

5. DataSyncFactoryUtil.discoverSource 这个是source的实例化重点

SourceFactory sourceFactory = DataSyncFactoryUtil.discoverSource(config, env);

a.主要是根据配置json中的插件名,反射到对应的connector

 return ClassLoaderManager.newInstance(
            urlList,
            cl -> {
                Class<?> clazz = cl.loadClass(pluginClassName);
 Constructor<?> constructor =
                    clazz.getConstructor(
                            SyncConf.class, StreamExecutionEnvironment.class);
 return (SourceFactory) constructor.newInstance(config, env);
 });

b.通过connector可以得到一个SourceFactory的实例(这里的SourceFactory概念,相当于旧版本FlinkX的Reader)
如果我们想自定义一个source,核心是实现SourceFactory,InputFormat,和InputFormatBuilder
InputFormatBuilder负责生成InputFormat,SourceFactory的createSource方法通过InputFormat生成dataStream。

以HDFS和JDBC为例,这里的flink,flinkX,用户自定义接口的继承和实现关系可以参考下图:
在这里插入图片描述

6.调用factory的createSource获得ds后,根据Reader配置调整parallelism,转换sql,reblance等,如果有转换sql,还需要将ds注册成Table

if (transformer) {
        dataStream = syncStreamToTable(tableEnv, config, dataStreamSource);
}

7. DataSyncFactoryUtil.discoverSink 这个是sink的实例化重点。

SinkFactory sinkFactory = DataSyncFactoryUtil.discoverSink(config);
DataStreamSink<RowData> dataStreamSink = sinkFactory.createSink(dataStream);

实现规范类似source

自定义Sink端的话,需要实现SinkFactory,OutputFormat,和OutputFarmatBuilder
最后是通过createSink,获得dsSink对象

8.根据Writer配置,调整parallelism
9.env.execute 启动flink作业,如果是本地模式,会将结果打印

JobExecutionResult result = env.execute(options.getJobName());
 if (env instanceof MyLocalStreamEnvironment) {
    PrintUtil.printResult(result.getAllAccumulatorResults());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值