需求:
我目前正在做实时大数据平台,我们想在部署平台的时和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方法即可。
我们经过上述代码已经明确的知道了,他执行的是cli的run方法,这个方法在FlinkYarnSeesionCli,我们点进去看一看。
我们先来看看run方法中配置的封装,他将我们命令行中输入的参数替换掉了我们flink-conf.yml中配置。
设置部署模式为seesion模式,因为我们要启动的方式也就是session。
然后获取了一个yarn集群描述器,就来看看这个集群描述器是怎么创建出来的。
我们就看到了,我们可以发现,我们根据hadoop、flink的配置以及yarn的配置就可以构建出来一个YarnClusterDescriptor。
我们发现我们从flink的配置中将yarn的配置切出来了,同时hadoop的配置也是同理。
通过这一段代码,我们就可以部署起来一个session任务了,启动调用了deploySessionCluster,如果有兴趣的话,可以去看一看这个deploySessionCluster的方法。他启动了一个AppMaster。
有兴趣的话,可以继续往下看,当然源码是看不完的,我一般是有需求的时候才会去看源码。或者是在一些课程上。接下来我就和大家分享一下,我们看了源码有什么用?
多了就不说了,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);
}
}
这些知识都是我学习来的一些东西,我也是一个菜鸡,只是想把自己学到的东西记录一下,生成自己的一些知识做一些记录以后找的时候方便,现在分享给大家,谢谢大家的观看。