java实现发布flink yarn session模式作业

一.背景

在企业级实时大数据处理场景中,Apache Flink 凭借低延迟、高吞吐的流处理能力,成为日志分析、实时计算、事件驱动型应用的核心引擎;而 YARN 作为 Hadoop 生态的主流资源调度系统,是企业私有化大数据集群的标准资源管理底座。Flink YARN Session 模式通过预先申请集群资源并启动常驻的 Flink 集群(Session Cluster),可复用资源承接多个作业提交,相比 Per-Job 模式大幅降低资源申请与集群启动的开销,适配高频、小规模作业的运行诉求。但传统的 Flink YARN Session 作业发布方式(如 flink run 命令行、脚本化提交)已难以满足企业对 "标准化、自动化、可管控" 的运维要求,基于 Java 实现程序化发布 Flink YARN Session 作业,成为解决传统痛点、适配企业级落地的核心选择。

  1. 发布流程碎片化,自动化能力不足 传统发布依赖 flink run -m yarn-session://<yarn-jobmanager-addr> 命令行手动执行,或通过 Shell 脚本封装参数,存在显著短板:一是参数配置繁琐(如指定 YARN Session 地址、作业并行度、内存配额、依赖包、主类等),易因参数拼写错误、版本不兼容导致作业提交失败;二是难以集成至企业 CI/CD 流水线、运维平台等自动化体系,大量依赖人工操作,发布效率低且易引发人为故障;三是测试 / 生产等多环境的配置(如 YARN 队列、资源大小、数据源地址)需手动修改脚本,缺乏统一的配置管理机制,环境一致性难以保障。

  2. Session 集群与作业管控能力缺失 flink run 仅能完成作业 "提交" 动作,无法程序化管控 YARN Session 集群及作业全生命周期:提交后无法实时获取作业在 Session 集群中的运行状态(RUNNING/FAILED/CANCELED)、资源使用情况;作业异常时无法自动重试或触发告警;需人工登录 Flink WebUI、YARN ResourceManager 控制台查询状态,运维成本高,且无法快速响应作业故障;同时,对 YARN Session 集群的创建、销毁、资源扩容等操作也需手动执行,无法根据作业负载动态调整。

  3. 与企业级系统集成性差 企业级场景中,作业发布需对接权限管控、资源审批、日志审计、成本计量等系统,但 flink run 作为独立命令行工具,无法直接联动这些系统:例如,提交前无法校验用户是否有 YARN Session 所在队列的使用权限,提交后无法自动记录作业的资源消耗用于成本核算,作业日志无法自动归集至企业统一日志平台,难以满足合规与精细化运维诉求。

  4. 多 Session 集群 / 多版本适配困难 企业往往部署多套 YARN Session 集群(如测试 / 生产、不同业务专属集群)、多个 Flink 版本,传统脚本化发布需为不同集群 / 版本维护不同的 flink run 脚本,版本兼容、集群地址切换成本高;且无法程序化识别 YARN Session 集群的可用状态,易将作业提交至异常的 Session 集群,导致作业运行失败。

Java 作为 Flink 底层开发的核心语言,也是企业级应用开发的主流语言,基于 Java 实现 Flink YARN Session 作业的程序化发布,本质是构建 "标准化、自动化、可管控" 的作业发布体系,解决传统方式的痛点:

  1. 标准化发布接口,提升自动化水平 基于 Flink 官方提供的 FlinkYarnSessionCliClusterClient 等 Java API 封装统一的发布接口,将 YARN Session 作业的核心配置(Session 集群地址、主类、jar 包路径、并行度、内存配额、YARN 队列等)抽象为可配置参数,替代碎片化的 flink run 命令。该接口可无缝集成至企业 CI/CD 流水线(Jenkins、GitLab CI)、大数据调度平台,实现 "代码编译 - 打包 - 作业发布 - 状态校验" 的全流程自动化,减少人工干预,降低发布错误率。

  2. 全生命周期管控,强化运维能力Java 程序可通过 Flink Rest API、YARN ResourceManager REST API 联动 Session 集群与作业:提交作业后实时监听作业状态,捕获运行异常、失败、终止等状态变更;作业失败时自动触发重试逻辑,或推送告警至企业监控平台(如 Prometheus、AlertManager);作业运行中可查询并行度、CPU / 内存使用情况,拉取作业日志并归集至 ELK 等统一日志系统;同时可程序化管理 YARN Session 集群,根据作业负载动态创建、销毁、扩容 Session 集群,提升资源利用率。

  3. 深度集成企业级系统,满足合规诉求Java 发布程序可对接企业现有系统:提交作业前调用权限系统校验用户 / 应用对 YARN 队列、Flink Session 集群的使用权限;提交过程中记录审计日志(提交人、时间、配置、集群信息),满足合规审计要求;作业运行后将资源消耗数据同步至成本计量系统,实现作业成本的精细化核算;同时可集成 Nacos、Apollo 等配置中心,统一管理多环境配置,避免手动修改脚本导致的配置不一致问题。

  4. 灵活适配多集群 / 多版本场景通过 Java 程序的配置化设计,将不同 YARN Session 集群的连接信息(JobManager 地址、YARN ResourceManager 地址)、不同 Flink 版本的适配参数封装为配置项,发布作业时按需加载对应配置,无需修改核心代码即可适配多集群、多版本场景。例如,通过配置中心切换测试 / 生产 Session 集群地址,一键发布作业至目标集群,降低环境适配成本。

3.典型应用场景

  1. 企业级实时计算平台作业发布:构建统一的 Flink 实时计算平台,基于 Java 实现 YARN Session 作业的标准化发布入口,支撑各业务部门提交实时日志分析、交易风控、用户行为计算等作业,统一管控 Session 集群资源、作业权限、运行日志,提升平台易用性与可维护性。
  2. 高频小作业的高效发布:零售、互联网等行业的实时指标计算、实时告警等高频小作业,通过 Java 程序发布至常驻的 YARN Session 集群,复用集群资源避免重复申请,降低作业启动延迟,保障实时计算的低延迟诉求。
  3. 多 Session 集群的统一管控:企业为不同业务线部署专属 YARN Session 集群,通过 Java 程序实现作业的批量发布、状态统一监控,适配业务隔离与资源按需分配的需求,同时支持跨集群作业容灾切换。
  4. 业务系统触发的实时计算:订单系统、支付系统等业务系统触发实时数据计算需求时,通过 Java 接口直接发布 Flink YARN Session 作业,作业完成后将计算结果回调至业务系统,实现 "业务触发 - 实时计算 - 结果返回" 的闭环。

综上,Java 实现发布 Flink YARN Session 模式作业,是企业将 Flink 实时计算能力从 "手工运维" 转向 "工程化、自动化管控" 的关键路径:既充分利用 Flink YARN Session 模式的资源复用优势,又通过 Java 语言的企业级特性,解决发布碎片化、管控缺失、集成性差等痛点,适配企业级实时大数据处理的规模化、规范化诉求,为低延迟、高吞吐的实时计算场景提供稳定、可管控的发布支撑。

二.具体实现

1.引入依赖

复制代码
<dependency>
	<groupId>org.apache.flink</groupId>
	<artifactId>flink-yarn</artifactId>
	<version>1.18.1</version>
</dependency>
<dependency>
	<groupId>org.apache.flink</groupId>
	<artifactId>flink-clients</artifactId>
	<version>1.18.1</version>
</dependency>
<dependency>
	<groupId>org.apache.hadoop</groupId>
	<artifactId>hadoop-yarn-api</artifactId>
	<version>3.2.1</version>
</dependency>

2.定义flink参数

复制代码
Configuration flinkConfig = new Configuration();

    flinkConfig.setString(JobManagerOptions.TOTAL_FLINK_MEMORY.key(), "1024m");
    flinkConfig.setString(TaskManagerOptions.TOTAL_FLINK_MEMORY.key(), "1024m");
    flinkConfig.setInteger(TaskManagerOptions.NUM_TASK_SLOTS, 4);
    flinkConfig.setString(CoreOptions.FLINK_HADOOP_CONF_DIR, "/opt/teh/core/hadoop/etc/hadoop");
    flinkConfig.setString(YarnConfigOptions.APPLICATION_TYPE, "Flink");
    ... ...

3.定义客户端

复制代码
YarnClusterDescriptor clusterDescriptor = null;
PackagedProgram packageProgram = null;
ClusterClient<ApplicationId> client = null;

DefaultClusterClientServiceLoader serviceLoader = new DefaultClusterClientServiceLoader();
ClusterClientFactory<ApplicationId> clientFactory = serviceLoader.getClusterClientFactory(flinkConfig);
ApplicationId yarnClusterId = clientFactory.getClusterId(flinkConfig);


clusterDescriptor = (YarnClusterDescriptor) clientFactory.createClusterDescriptor(flinkConfig);

4.定义flink作业的配置

复制代码
List<String> argList = flinkConfig
        .getOptional(ApplicationConfiguration.APPLICATION_ARGS)
        .orElse(Lists.newArrayList());

SavepointRestoreSettings srs = SavepointRestoreSettings.forPath("");

packageProgram = PackagedProgram.newBuilder()
        .setArguments(argList.toArray(new String[argList.size()]))
        .setEntryPointClassName(
                flinkConfig.getOptional(ApplicationConfiguration.APPLICATION_MAIN_CLASS).get()
        )
        .setSavepointRestoreSettings(srs)
        .build();

JobGraph jobGraph = PackagedProgramUtils.createJobGraph(
        packageProgram,
        flinkConfig,
        10,
        null,
        false
);

5.发布作业

复制代码
client = clusterDescriptor.retrieve(yarnClusterId).getClusterClient();
String jobId = client.submitJob(jobGraph).get().toString();
String jobManagerUrl = client.getWebInterfaceURL();
相关推荐
Qiuner7 小时前
Spring Boot 机制五: Bean 生命周期与后置处理器(BeanPostProcessor)源码深度剖析
java·spring boot·后端
qq_12498707537 小时前
基于Spring Boot的阳光餐盘点餐系统(源码+论文+部署+安装)
java·vue.js·spring boot·后端·毕业设计
程序员三明治7 小时前
【Java基础】序列化到底是什么?有什么用?实现原理?
java·开发语言·后端·java基础·序列化·反序列化
Full Stack Developme7 小时前
Java实现Word、Excel、PDF文件 在线预览
java·word·excel
武子康7 小时前
Java-185 Guava Cache 实战:删除策略、过期机制与常见坑全梳理
java·spring boot·redis·spring·缓存·guava·guava cache
阿杰同学7 小时前
Java 网络协议面试题答案整理,最新面试题
java·开发语言·网络协议
天天向上杰7 小时前
spark、mapreduce、flink核心区别及浅意理解
flink·spark·mapreduce
诗旸的技术记录与分享7 小时前
Flink-1.19.0源码详解11-Flink ResourceManager资源调度
大数据·flink
CoderYanger7 小时前
动态规划算法-两个数组的dp(含字符串数组):41.最长公共子序列(模板)
java·算法·leetcode·动态规划·1024程序员节