Java提交Flink程序(Session)

需求:

我目前正在做实时大数据平台,我们想在部署平台的时和hadoop解耦,也就是我不需要部署到hadoop的机器上,同事我司采用的是yarn session模式,此时我也就有了一个方式,我不用命令调用,我直接拿java起不就行了吗,因为flink也是java写的啊,我们只要模仿着flink怎么提交的,我们来做一番不就可以了吗,那么我们就看看flink怎么做的吧。

我们在阅读源码之前需要找到根源,我们要看的是什么?

我们来分析一下,我们在Yarn启动一个Yarn Session 的逻辑是什么?肯定是用命令启动的,对吧,我们就来分析一下shell脚本。

bin=`dirname "$0"`
bin=`cd "$bin"; pwd`

# get Flink config
. "$bin"/config.sh

if [ "$FLINK_IDENT_STRING" = "" ]; then
        FLINK_IDENT_STRING="$USER"
fi

JVM_ARGS="$JVM_ARGS -Xmx512m"

CC_CLASSPATH=`manglePathList $(constructFlinkClassPath):$INTERNAL_HADOOP_CLASSPATHS`

log=$FLINK_LOG_DIR/flink-$FLINK_IDENT_STRING-yarn-session-$HOSTNAME.log
log_setting="-Dlog.file="$log" -Dlog4j.configuration=file:"$FLINK_CONF_DIR"/log4j-session.properties -Dlog4j.configurationFile=file:"$FLINK_CONF_DIR"/log4j-session.properties -Dlogback.configurationFile=file:"$FLINK_CONF_DIR"/logback-session.xml"

$JAVA_RUN $JVM_ARGS -classpath "$CC_CLASSPATH" $log_setting org.apache.flink.yarn.cli.FlinkYarnSessionCli -j "$FLINK_LIB_DIR"/flink-dist*.jar "$@"

此时我们就在最后一行看出来了,我们启动的是哪个类?FlinkYarnSessionCli 是不是太明确不过了。源码入口已经找到了,接下来就看看他到底做了什么?

因为我们要看的是一个类,此时我们明白,使用java 命令调用的肯定是 这个类的main方法,我们就看他的main方法即可。

image-20220407150844291

我们经过上述代码已经明确的知道了,他执行的是cli的run方法,这个方法在FlinkYarnSeesionCli,我们点进去看一看。

image-20220407151440005

我们先来看看run方法中配置的封装,他将我们命令行中输入的参数替换掉了我们flink-conf.yml中配置。

image-20220407154429890

设置部署模式为seesion模式,因为我们要启动的方式也就是session。

然后获取了一个yarn集群描述器,就来看看这个集群描述器是怎么创建出来的。

image-20220407154723507

我们就看到了,我们可以发现,我们根据hadoop、flink的配置以及yarn的配置就可以构建出来一个YarnClusterDescriptor。

image-20220407154911107

我们发现我们从flink的配置中将yarn的配置切出来了,同时hadoop的配置也是同理。

image-20220407155526776

通过这一段代码,我们就可以部署起来一个session任务了,启动调用了deploySessionCluster,如果有兴趣的话,可以去看一看这个deploySessionCluster的方法。他启动了一个AppMaster。

image-20220407155812477

有兴趣的话,可以继续往下看,当然源码是看不完的,我一般是有需求的时候才会去看源码。或者是在一些课程上。接下来我就和大家分享一下,我们看了源码有什么用?

多了就不说了,show you code,大部分的代码都是在flink源码中抄录的,这样你就不用重复造轮子了,对吗?假如公司让你用pre job方式提交任务,你会了吗?Standalone呢?都大概是相同的模式,我们抄一抄,摘一摘,即可。

以下为测试代码,不为真正生产环境中代码。

/**
 * @author :qingzhi.wu
 * @date :2022/4/6 3:59 下午
 */
public class SubmitJobToYarn {
    public static void main(String[] args) throws ClusterDeploymentException {
        
        
        System.setProperty("HADOOP_USER_NAME","xxx");
        String flinkLibs = "hdfs://xx:8280/flink/lib";
        String flinkLibs2 = "hdfs://xx:8280/flink/plugins";
        //String flinkDistJar = "hdfs://xx:8280/flink/lib/flink-yarn_2.12-1.11.2.jar";
        Configuration flinkConfiguration = new Configuration();
        //最小配置
        flinkConfiguration.setString("flink.yarn.resourcemanager.hostname","xx");
        flinkConfiguration.setString("flink.hadoop.fs.defaultFS","hdfs://xx:8280");
        //flinkConfiguration.setString("flink.hadoop.fs.hdfs.impl","org.apache.hadoop.hdfs.DistributedFileSystem");

        //设置配置,可以设置很多
        List<String> jars = new ArrayList<>();
        jars.add(flinkLibs);
        jars.add(flinkLibs2);
        flinkConfiguration.set(
                YarnConfigOptions.PROVIDED_LIB_DIRS,
                jars);
        //设置为application模式
        flinkConfiguration.set(
                DeploymentOptions.TARGET,
                YarnDeploymentTarget.SESSION.getName());



        flinkConfiguration.set(JobManagerOptions.TOTAL_PROCESS_MEMORY, MemorySize.parse("1024", MEGA_BYTES));
        flinkConfiguration.set(TaskManagerOptions.TOTAL_PROCESS_MEMORY, MemorySize.parse("1024", MEGA_BYTES));

        YarnClusterDescriptor yarnClusterDescriptor = getClusterDescriptor(flinkConfiguration);

        ClusterSpecification clusterSpecification =
                new ClusterSpecification.ClusterSpecificationBuilder().createClusterSpecification();

        ClusterClientProvider<ApplicationId> clusterClientProvider = null;
        try {
            clusterClientProvider = yarnClusterDescriptor.deploySessionCluster(clusterSpecification);
        } catch (ClusterDeploymentException e) {
            e.printStackTrace();
        }

        ClusterClient<ApplicationId> clusterClient = clusterClientProvider.getClusterClient();
        ApplicationId applicationId = clusterClient.getClusterId();
        System.out.println(applicationId);
    }


    private static YarnConfiguration getYarnAndHadoopConfiguration(Configuration flinkConfig) {
        final YarnConfiguration yarnConfig = new YarnConfiguration();
        String[] YARN_FLINK_CONFIG_PREFIXES = {"flink.yarn.","flink.hadoop."};
        for (String key : flinkConfig.keySet()) {
            for (String prefix : YARN_FLINK_CONFIG_PREFIXES) {
                if (key.startsWith(prefix)) {
                    String newKey = key.substring("flink.".length());
                    String value = flinkConfig.getString(key, null);
                    yarnConfig.set(newKey, value);
                }
            }
        }

        String[] HADOOP_FLINK_CONFIG_PREFIXES = {"flink.hadoop."};
        org.apache.hadoop.conf.Configuration result = new HdfsConfiguration();
        for (String key : flinkConfig.keySet()) {
            for (String prefix : HADOOP_FLINK_CONFIG_PREFIXES) {
                if (key.startsWith(prefix)) {
                    String newKey = key.substring(prefix.length());
                    String value = flinkConfig.getString(key, null);
                    result.set(newKey, value);
                }
            }
        }
        yarnConfig.addResource(result);
        return yarnConfig;
    }

    private static YarnClusterDescriptor getClusterDescriptor(Configuration configuration) {
        final YarnClient yarnClient = YarnClient.createYarnClient();
        final YarnConfiguration yarnConfiguration =
                getYarnAndHadoopConfiguration(configuration);

        yarnClient.init(yarnConfiguration);
        yarnClient.start();

        return new YarnClusterDescriptor(
                configuration,
                yarnConfiguration,
                yarnClient,
                YarnClientYarnClusterInformationRetriever.create(yarnClient),
                false);
    }
}

这些知识都是我学习来的一些东西,我也是一个菜鸡,只是想把自己学到的东西记录一下,生成自己的一些知识做一些记录以后找的时候方便,现在分享给大家,谢谢大家的观看。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值