flink源码启动解析

flink是近来比较热门的实时流计算引擎,相信大家对于其使用并不陌生。但是使用怎么能是我们追求的重点,本着打破砂锅问到底的态度(其实就是上班划水,不要找借口了)

我们一起从头开始,研究flink源码,在这之中无形的拓宽知识面。既然开始,就从最前面开始,首先从sh脚本开始分析

1、我们在本地集群运行时,首先使用到的命令就是start-cluster.sh脚本启动,查看脚本内容我们不难发现,不管是启动HA模式,还是非HA模式,都会执行jobmanager.sh脚本,这里的STARTSTOP=$1,其实就是STARTSTOP=start,所以这里会走flink-daemon.sh,在flink-daemon.sh我们可以看到指向的启动类,

我们主要研究一下单机集群启动类org.apache.flink.runtime.entrypoint.standalonesessionclusterentrypoint类

flink源码启动解析_第1张图片

 

2、那废话不多说,我们先查看StandaloneSessionClusterEntrypoint启动源码,StandaloneSessionClusterEntrypoint继承自SessionClusterEntrypoint

主要执行逻辑我将以注释的形式标注在代码之中

// startup checks and logging
// 进行启动检查,获取启动环境信息,如版本,scala版本,git提交号,jvm版本,hadoop版本,javahome等
EnvironmentInformation.logEnvironmentInfo(LOG, StandaloneSessionClusterEntrypoint.class.getSimpleName(), args);
// 捕捉系统信号windows包含:终止(TERM),INT(键盘中断);其它系统多包含:HUP(终端挂起或者控制进程终止)
SignalHandler.register(LOG);
// 注册JVM关闭的钩子函数 设置5秒延迟退出
JvmShutdownSafeguard.installAsShutdownHook(LOG);

// 获取启动行参数,使用的是org.apache.commons.cli
// 所有的启动参数都写在了org.apache.flink.runtime.entrypoint.parser.CommandLineOptions类中
// 包括:
// c configDir: Directory which contains the configuration file flink-conf.yml.
// r webui-port: Port for the rest endpoint and the web UI.
// D property=value: use value for given property
// h host: Hostname for the RPC service.
// x executionMode: Deprecated option
EntrypointClusterConfiguration entrypointClusterConfiguration = null;
final CommandLineParser commandLineParser = new CommandLineParser<>(new EntrypointClusterConfigurationParserFactory());

try {
   entrypointClusterConfiguration = commandLineParser.parse(args);
} catch (FlinkParseException e) {
   LOG.error("Could not parse command line arguments {}.", args, e);
   commandLineParser.printHelp(StandaloneSessionClusterEntrypoint.class.getSimpleName());
   System.exit(1);
}
// 获取到参数
Configuration configuration = loadConfiguration(entrypointClusterConfiguration);

StandaloneSessionClusterEntrypoint entrypoint = new StandaloneSessionClusterEntrypoint(configuration);
// 运行 执行父类方法
ClusterEntrypoint.runClusterEntrypoint(entrypoint);

 

3、然后我们看看运行后,进入SessionClusterEntrypoint的startCluster方法

  // 加载插件,从文件系统找jar包
   PluginManager pluginManager = PluginUtils.createPluginManagerFromRootFolder(configuration);
   // 初始化共享文件系统设置,会将文件系统映射为url
   configureFileSystems(configuration, pluginManager);

   // 初始化安全上下文:其中为进程范围的安全配置,使用可用的安全模块(即Hadoop、JAAS)应用配置。
   SecurityContext securityContext = installSecurityContext(configuration);


   securityContext.runSecured((Callable) () -> {
      runCluster(configuration, pluginManager);

      return null;
   });

 

4、接下来进入runCluster方法之后,由于展开来讲过多,具体每个模块我将在后续文章一一解析,我将按照代码执行的顺序按行解释,大家可以按照源码对照分析

一、初始化集群服务

initializeServices(configuration, pluginManager);

创建通用RPC服务,会从配置中获取地址,端口范围,绑定本地host和端口号,其中RPC服务使用的是AKKA

 

  • 1.使用SecurityManager返回当前线程组,新建fix线程池,创建高可用服务
createHaServices(configuration, ioExecutor);

其中共有三种模式:

1、NONE:创建高可用服务,根据资源管理器地址,调度地址,监控地址,生成单机高可用服务

2、ZOOKEEPER:使用ZooKeeper,服务将数据存储在ZooKeeper的节点中,结构如下,其中每个集群独立目录:

/flink

 /cluster_id_1/resource_manager_lock

       /job-id-1/job_manager_lock

 /checkpoints/latest

       /latest-1

       /latest-2

       /job-id-2/job_manager_lock

 /cluster_id_2/resource_manager_lock

              /job-id-1/job_manager_lock

 /checkpoints/latest

       /latest-1

/persisted_job_graph

3、FACTORY_CLASS:创建自定义的高可用服务

  • 1.创建BLOB server:BLOB服务器负责侦听传入请求并生成线程来处理这些请求。此外,它还负责创建目录结构来存储blob或临时缓存它们。
  • 2.创建心跳服务
  • 3.创建指标服务,包括机器系统指标:Hostname,CPU,Memory,Thread,GC,NetWork,IO 和 任务运行组件指标:JobManager,TaskManager,Job, Task,Operater相关指标。通过com.codahale.metrics实现
  • 4.创建序列化执行图存储

二、根据上述服务创建资源,调度,监控进程DispatcherResourceManagerComponent,并设置同步状态关闭,这之中还包含网关及查询服务检索器的创建,将在后续文章中一一详解。至此,启动结束。

总结:现在我们基本了解了flink启动读取运行参数,获取本地配置,并增加了JVM关闭钩子等一些我们平常开发不常用的一些方法,并大致了解flink的分布式的实现方案,在后续的文章中,我们具体看看flink是如何实现这些服务,并管理好task,保证服务的稳定性的。

 

你可能感兴趣的:(开发记录,java,flink,大数据,分布式,linux)