Flink 集群运行模式

文章目录

一、三种运行模式的划分依据

Flink 集群运行模式根据两个条件划分为三种类型:

划分维度 问题
条件 1 集群生命周期与资源隔离方式 — 共享还是独占?
条件 2 main 方法在哪里执行 — Client 端还是 JobManager 端?

三种模式:

Session Mode    ──── 共享集群,main 在 Client
Per-Job Mode    ──── 独占集群,main 在 Client
Application Mode ─── 独占集群,main 在 JobManager

二、Session Mode(会话模式)

2.1 核心架构

                Session 集群(提前启动,长期运行)
        ┌───────────────────────────────────────────────┐
        │          JobManager(共享)                     │
        │              │                                 │
        │    ┌─────────┼─────────┐                       │
        │    ▼         ▼         ▼                       │
        │  Job-1     Job-2     Job-3   ← 多个作业共享     │
        │    │         │         │                       │
        │    └─────────┼─────────┘                       │
        │              ▼                                 │
        │     TaskManager(s)(共享)                       │
        └───────────────────────────────────────────────┘
              ▲          ▲          ▲
              │          │          │
          Client-1   Client-2   Client-3

关键特征:JobManager 和 TaskManager 预先启动,多个作业共享同一套集群资源,JobManager 生命周期独立于作业——作业停止不影响集群存活。

2.2 优缺点

维度 评价
资源利用率高 多作业共享集群,资源充分复用
运维简单 一个集群管理所有作业
启动快 集群预启动,作业提交即运行,无需等待资源分配
资源隔离弱 作业间资源竞争,Job-1 占满可能导致 Job-2 无法提交
伸缩性弱 TaskManager 启动时固定,难以动态扩缩(除非配合 Native K8s)

三、Per-Job Mode(每作业模式)

3.1 核心架构

  Job-1                               Job-2
  ┌──────────────────────┐           ┌──────────────────────┐
  │  JobManager-1(独占)  │           │  JobManager-2(独占)  │
  │        │              │           │        │              │
  │  TaskMgr-A  TaskMgr-B │           │  TaskMgr-C  TaskMgr-D │
  │  [Slot][Slot][Slot]   │           │  [Slot][Slot]         │
  └──────────────────────┘           └──────────────────────┘
       独立的集群实例                       独立的集群实例

关键特征:每个作业拥有一套独立的 JobManager + TaskManager,Job-1 和 Job-2 之间的集群资源完全隔离。作业执行完毕后,整个集群销毁释放。

3.2 优缺点

维度 评价
资源隔离强 作业间互不影响
Slot 灵活 每个作业可按需配置 Task Slot 数量
资源浪费 每作业都启动一个 JobManager,消耗额外计算资源
管理复杂 大量 JobManager 实例,依赖 ClusterManager(YARN/K8s)统一管理
启动慢 每次提交都需要启动整套集群

四、Session vs Per-Job 的共同痛点

无论 Session 还是 Per-Job,main 方法都在 Client 端执行,带来一系列问题:

Client 端执行 main 方法的问题:

1. 依赖 JAR 下载     → 每次提交都要从远端下载,大 JAR(十几到几百 MB)消耗带宽
2. JobGraph 生成     → 消耗 Client 本地 CPU 资源
3. JAR 上传         → 每次提交都要通过 RPC 上传 JAR 到 JobManager,重度网络消耗
4. 阻塞式提交        → 提交是同步阻塞的,多用户提交需要排队等待
5. Client 瓶颈       → 单 Client 提交多作业时压力巨大,稳定性无法保证
传统模式:Client 承载了太多
┌──────────┐      下载依赖       ┌──────────┐      上传 JAR        ┌──────────┐
│  远端仓库  │ ──────────────────→ │  Client  │ ──────────────────→ │JobManager│
└──────────┘    (网络消耗)        └──────────┘    (网络消耗)        └──────────┘
                                    │
                              执行 main 方法
                              生成 JobGraph
                              (CPU 消耗)

五、Application Mode(应用模式)

5.1 核心理念

main 方法从 Client 端搬到 JobManager 端执行!

Application Mode 的变革:

之前:Client 做所有重活      →    JobManager 只是调度
现在:Client 只发命令          →    JobManager 承担 main 方法执行 + JobGraph 生成

5.2 架构对比

传统模式(Session / Per-Job):

Client                                JobManager
  │                                      │
  ├─ 下载依赖 JAR                         ├─ 接收 JobGraph
  ├─ 执行 main 方法                       ├─ 生成 ExecutionGraph
  ├─ 生成 JobGraph                        └─ 调度 Task
  └─ 上传 JAR + JobGraph ──────────→


Application Mode:

Client                     JobManager(管理节点)
  │                          │
  └─ 只发命令 ──────→        ├─ 从 DFS 拉取依赖 JAR
                             ├─ 执行 main 方法
                             ├─ 生成 JobGraph
                             ├─ 生成 ExecutionGraph
                             └─ 调度 Task

5.3 Application Mode 的工作流程

1. Client 发送提交命令
        │
2. JobManager 从分布式文件系统(DFS/HDFS)拉取依赖 JAR
        │
3. JobManager 执行 main 方法 → 生成 JobGraph
        │
4. JobManager 调度 → TaskManager 执行
        │
5. 一个 Application = 一套独立集群(类似 Per-Job)
   一个 Application 内可以包含多个 Job

5.4 优缺点

维度 评价
Client 轻量化 Client 只需发命令,无需本地下载/上传/执行,负载大幅降低
网络优化 JAR 从 DFS 直接拉取到集群,避免 Client ↔ JobManager 的大流量传输
避免排队 每个 Application 独立执行 main 方法,不再阻塞提交
Application 级隔离 每个 Application 启动独立集群,资源隔离
只支持 YARN / K8s 暂不支持 Standalone
K8s 需预构建镜像 K8s 上需要提前把用户程序打成 Docker 镜像

六、三种模式全景对比

维度 Session Per-Job Application
集群生命周期 独立于作业,长期运行 绑定作业,作业结束即销毁 绑定 Application,结束即销毁
资源隔离 弱(共享集群) 强(独占集群) 强(独占集群)
main 方法位置 Client Client JobManager
JobGraph 生成位置 Client Client JobManager
Client 负载 ✅ 低
资源利用率 ✅ 高 ❌ 低
提交速度 ✅ 快(集群预热) ❌ 慢(每次启动集群)
运维复杂度 ✅ 低 ❌ 高
适用场景 短作业、多作业共享 大作业、需严格隔离 流平台、多用户提交
支持平台 Standalone/YARN/K8s YARN/K8s 仅 YARN / K8s

七、如何选择运行模式?

                    开始
                     │
         ┌─ 需要强资源隔离? ──┐
         │ 否              │ 是
         ▼                 ▼
    Session Mode    ┌─ main 在哪执行? ──┐
    (短作业/开发测试)  │ Client        │ JobManager
                      ▼               ▼
                 Per-Job Mode    Application Mode
                 (大作业/生产)    (流平台/多租户)

八、小结

  1. Flink 有三种集群运行模式,按集群生命周期main 方法位置两个维度划分
  2. Session 适合短作业共享集群,资源利用率高但隔离弱
  3. Per-Job 适合大作业独占集群,隔离强但资源浪费
  4. Application Mode 将 main 方法迁到 JobManager,解决了传统模式 Client 瓶颈问题,是流平台多租户场景的未来方向
  5. Application Mode 目前仅支持 YARN 和 K8s