基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

Flink on YARN 部署模式详解

知识点图片

本文讲解Flink on YARN的三种作业提交流程:Session模式共享集群,适合小作业;Per-Job模式为每作业启动集群;Application模式将应用逻辑在集群端执行,资源隔离性最佳,是官方推荐的生产模式。

Flink on YARN 是生产环境中最常用、最稳定的部署模式。它利用 YARN(Yet Another Resource Negotiator)作为资源管理器,让 Flink 应用能够按需获取和释放计算资源,并与其他大数据框架(如 Spark, MapReduce)共享同一个集群。

作业提交流程的核心区别在于 Flink 集群的生命周期和 main() 方法的执行位置。据此,Flink on YARN 主要分为三种模式:

  1. Application Mode (应用模式) - 官方推荐
  2. Per-Job Mode (单作业模式) - 传统模式
  3. Session Mode (会话模式)

下面我们将详细讲解每种模式的提交流程。


核心组件角色

在深入流程之前,先明确几个关键角色:

  • Client: 你执行 flink run ... 命令的机器。它负责准备作业所需的文件、与 YARN ResourceManager 交互。
  • YARN ResourceManager (RM): YARN 集群的主节点,负责整个集群的资源分配和管理。
  • YARN NodeManager (NM): YARN 集群中每个工作节点上的代理,负责管理该节点上的容器(Container)。
  • Flink ApplicationMaster (AM): Flink on YARN 的核心。它首先由 ResourceManager 启动在一个容器中。它的职责包括:
    • 作为 Flink 的 JobManager (JM)
    • 向 ResourceManager 申请更多的容器来运行 TaskManager。
    • 监控 Flink 作业的执行。
  • Flink TaskManager (TM): Flink 的工作节点,负责执行具体的计算任务(Task)。每个 TaskManager 运行在一个由 ApplicationMaster 申请来的 YARN 容器中。

1. Application Mode (应用模式) - 推荐

这是 Flink 1.11 版本后引入并作为首选的模式。它的核心思想是:整个 Flink 应用(包括 main() 方法)都在 YARN 集群上执行

Flink on YARN Application Mode

提交流程:

  1. 客户端提交 (Client)

    • 用户在 Client 节点上执行 bin/flink run-application -t yarn-application ... 命令。
    • Flink Client 对命令进行简单的语法校验。
    • Client 将 Flink 框架的 Jar 包、用户应用的 Jar 包以及相关依赖上传到 HDFS 等共享存储上。
    • Client 向 YARN ResourceManager 发起一个“启动应用”的请求。此时,Client 的任务基本完成,可以立即退出,作业的生命周期与 Client 完全解耦。
  2. 启动 ApplicationMaster (AM / JobManager)

    • YARN ResourceManager 收到请求后,在集群中找到一个可用的 NodeManager,并指示它启动一个容器(Container)。
    • 在这个容器内,Flink 的 ApplicationMaster 进程被启动。
  3. 在 AM 中执行应用代码

    • ApplicationMaster 启动后,它会下载之前上传到 HDFS 的用户 Jar 包。
    • 关键步骤: ApplicationMaster 在自己的 JVM 中直接调用用户 Jar 包的 main() 方法
    • main() 方法中的 Flink 作业代码被执行,生成 JobGraph(作业图)。
  4. 申请并启动 TaskManager

    • ApplicationMaster (现在已经成为 JobManager) 根据 JobGraph 分析出作业所需的资源(例如需要多少个 TaskManager)。
    • JobManager 向 YARN ResourceManager 发起请求,申请 N 个容器来运行 TaskManager。
    • ResourceManager 在集群中分配 N 个容器,并通知对应的 NodeManager 启动它们。
  5. 作业执行

    • NodeManager 在分配到的容器中启动 Flink TaskManager 进程。
    • TaskManager 启动后,会向 JobManager (即 ApplicationMaster) 进行注册。
    • JobManager 收到所有 TaskManager 的注册后,将 JobGraph 中的计算任务分发给这些 TaskManager。
    • TaskManager 开始执行任务,作业正式运行。

优点:

  • 资源隔离性好: 每个应用都有自己独立的 Flink Master (JobManager),一个应用的失败不会影响其他应用。
  • main() 方法在集群端执行: 避免了客户端成为瓶颈(例如 main() 方法中有复杂的逻辑或需要下载大量元数据),也节省了客户端的网络带宽。
  • 真正的“提交后不管” (Fire and Forget): 客户端提交后即可下线,非常适合自动化调度系统。

2. Per-Job Mode (单作业模式)

这是 Application Mode 出现之前的标准模式。它和 Application Mode 很像,每个作业独享一个 Flink 集群,但main() 方法在客户端执行

提交流程:

  1. 客户端提交 (Client)

    • 用户执行 bin/flink run -t yarn-per-job ... 命令。
    • 关键步骤: Flink Client 在本地执行用户 Jar 包的 main() 方法,生成 JobGraph
    • Client 将 Flink 框架 Jar、用户 Jar 和生成的 JobGraph 文件上传到 HDFS。
    • Client 向 YARN ResourceManager 提交应用,请求启动 ApplicationMaster。
  2. 启动 ApplicationMaster (JobManager)

    • 与 Application Mode 相同,RM 在一个容器中启动 Flink AM。
  3. 启动 TaskManager

    • AM (JobManager) 启动后,它不需要执行 main() 方法,因为它直接从 HDFS 加载 Client 上传的 JobGraph
    • 后续流程与 Application Mode 完全相同:JobManager 根据 JobGraph 向 RM 申请 TaskManager 容器,TM 启动并注册,最后 JM 分发任务。
  4. 客户端角色

    • 在作业提交到 YARN 之后,客户端会持续轮询作业状态,直到作业进入 RUNNING 状态或最终状态(FINISHED, FAILED),然后客户端进程退出。

缺点:

  • 客户端瓶颈: 如果 main() 方法很重(例如需要连接外部服务获取配置),会消耗客户端资源并增加提交延迟。
  • 网络开销: JobGraph 可能很大,需要在客户端和集群之间传输。

Per-Job Mode 正在被 Application Mode 逐渐取代。


3. Session Mode (会话模式)

这种模式下,你先在 YARN 上启动一个长期运行的 Flink 集群(一个 JobManager 和多个 TaskManager),然后可以向这个共享的集群提交多个作业。

提交流程 (分两步):

第一步:启动 Flink Session Cluster

  1. 客户端启动会话
    • 用户执行 bin/yarn-session.sh 命令。
    • 这个脚本会向 YARN ResourceManager 申请启动一个 Flink 集群的 ApplicationMaster。
  2. 集群启动
    • RM 在容器中启动 Flink AM (JobManager)。
    • AM 根据启动参数(例如 -n 4 指定4个TaskManager)向 RM 申请固定数量的容器。
    • RM 分配容器,TaskManager 在其中启动并向 JobManager 注册。
    • 此时,一个 Flink 集群在 YARN 上已经准备就绪,处于“空闲”状态,等待作业提交。yarn-session.sh 客户端会打印出 JobManager 的地址并保持运行。

第二步:提交作业到已有会话

  1. 客户端提交作业
    • 另一个终端中,用户执行 bin/flink run ... 命令(无需指定 -t 参数,Flink 会自动发现正在运行的 YARN 会话)。
  2. 作业执行
    • Flink Client 连接到已经运行的 Session Cluster 的 JobManager。
    • Client 在本地执行 main() 方法生成 JobGraph,然后将其发送给 JobManager。
    • JobManager 收到 JobGraph后,将任务分发给集群中已有的、可能空闲的 TaskManager。
    • 作业开始在共享的 TaskManager 上执行。

优点:

  • 低延迟: 对于提交大量短时间、小型的作业非常高效,因为它省去了为每个作业启动 Flink Master 和 TaskManager 的开销。

缺点:

  • 资源隔离性差: 所有作业共享同一组 TaskManager。一个有问题的作业(如导致 OOM)可能会影响到同一会话中的所有其他作业。
  • 资源不灵活: 集群资源是预先分配的。如果没作业,资源闲置浪费;如果作业多,资源可能成为瓶颈。

总结与对比

特性 Session Mode (会话模式) Per-Job Mode (单作业模式) Application Mode (应用模式)
集群生命周期 手动启动,长期运行,多作业共享 与单个作业的生命周期绑定 与单个应用的生命周期绑定
资源隔离 差,所有作业共享资源 好,每个作业独占集群 最好,每个应用独占集群
main() 执行位置 客户端 客户端 集群端 (JobManager)
主要优点 提交小作业延迟低 资源隔离好 资源隔离好,无客户端瓶颈
主要缺点 资源隔离差,资源利用率不稳定 客户端可能成为瓶颈 /
适用场景 频繁执行的、短时间的临时查询/作业 传统的批处理或流处理作业 所有生产环境的流处理和批处理作业(推荐)

总而言之,对于绝大多数生产场景,请优先选择 Application Mode。它提供了最佳的资源隔离和运维便利性。Session Mode 则更适合交互式分析和开发测试环境。

00:00
00:00