2. Flink 架构与组件:运行时架构、JobManager、TaskManager、任务槽与并行度

Flink 的运行时架构采用经典的 主从(Master-Worker) 模型,核心组件包括 JobManager(主节点)和 TaskManager(工作节点)。理解这些组件的职责、交互方式以及任务槽与并行度的关系,是掌握 Flink 实时额度计算性能调优的基础。

2.1 Flink 运行时架构总览

Flink 集群启动后,JobManager 负责接收作业、生成执行计划、协调检查点;TaskManager 负责实际执行算子任务。客户端(Client)仅负责提交作业,不参与运行时计算。

核心原则: JobManager 是“大脑”,TaskManager 是“肌肉”。JobManager 不处理数据流,只做调度与协调;TaskManager 不参与全局决策,只执行分配的任务。
Flink 运行时架构总览 Flink 运行时架构总览 Client(客户端) JobManager(主节点) 调度器 | 资源管理器 | 检查点协调器 作业图 → 执行图 → 任务分发 TaskManager 1 任务槽 0 | 任务槽 1 数据交换 | 算子执行 TaskManager 2 任务槽 0 | 任务槽 1 数据交换 | 算子执行 TaskManager 3 任务槽 0 | 任务槽 1 数据交换 | 算子执行 说明:JobManager 将作业拆分为并行子任务,分发到多个 TaskManager 的任务槽中并行执行

2.2 JobManager 核心职责

JobManager 是 Flink 集群的 控制中枢,每个 Flink 集群至少有一个 JobManager(高可用模式下可配置多个)。

子组件 职责说明 实时额度计算场景
调度器 将作业图(JobGraph)转换为执行图(ExecutionGraph),分配任务到 TaskManager 决定额度计算算子的并行子任务分布
资源管理器 管理 TaskManager 的注册、申请与释放 动态扩缩容时协调任务槽资源
检查点协调器 触发、完成与恢复检查点(Checkpoint) 保证额度计算的精确一次语义
作业状态管理 维护作业的元数据、累加器、指标 监控额度计算延迟与吞吐量
高可用提示: 生产环境建议启用 JobManager 高可用(HA),通过 ZooKeeper 或 Kubernetes 选举主节点,避免单点故障导致额度计算中断。

2.3 TaskManager 与任务槽

TaskManager 是实际执行计算的工作节点。每个 TaskManager 包含多个 任务槽(Task Slot),任务槽是 Flink 中资源分配的最小单位。

2.3.1 任务槽的核心概念

  • 资源隔离: 每个任务槽拥有独立的 CPU 资源(通过线程隔离)和内存资源(通过内存管理器)。
  • 任务共享: 同一个任务槽可以运行多个子任务(Subtask),前提是这些子任务来自同一个作业的不同算子(Slot Sharing)。
  • 默认行为: 一个任务槽默认运行一个线程,但可以通过 Slot Sharing 将多个轻量算子合并到同一个槽中,减少资源碎片。

2.3.2 任务槽与并行度的关系

并行度(Parallelism)决定了一个算子有多少个并行子任务;任务槽数量决定了集群能同时运行多少个子任务。两者必须满足:

核心公式: 集群总任务槽数 ≥ 作业最大并行度。否则作业会因资源不足而无法启动。
概念 定义 配置方式 示例
任务槽 TaskManager 内的固定资源单元 taskmanager.numberOfTaskSlots 每个 TaskManager 设置 4 个槽
并行度 算子或作业的并行子任务数 setParallelism() 或 pipeline.default-parallelism 额度计算算子并行度设为 8
Slot Sharing 允许不同算子的子任务共享同一槽 slotSharingGroup() Source + Map + Sink 共享一个槽
任务槽与并行度关系 任务槽与并行度关系(Slot Sharing 示例) TaskManager 1 任务槽 0 Source[0] + Map[0] KeyBy[0] + Sink[0] (4 个子任务共享) 任务槽 1 Source[1] + Map[1] KeyBy[1] + Sink[1] (4 个子任务共享) TaskManager 2 任务槽 2 Source[2] + Map[2] KeyBy[2] + Sink[2] (4 个子任务共享) 任务槽 3 Source[3] + Map[3] KeyBy[3] + Sink[3] (4 个子任务共享) 关键结论 并行度 = 4 总任务槽 = 4 每个槽运行 4 个子任务 (Source、Map、KeyBy、Sink) Slot Sharing 减少资源碎片 额度计算场景: 4 个分区并行处理 用户额度数据

2.4 任务槽配置最佳实践

  • 推荐槽数: 每个 TaskManager 设置 1~8 个任务槽,具体取决于 CPU 核心数和内存大小。通常建议槽数 = CPU 核心数。
  • Slot Sharing 策略: 对于额度计算中的轻量算子(如 Map、Filter),开启 Slot Sharing 可显著提高资源利用率;对于重量算子(如大状态 KeyBy 窗口),建议单独分配 Slot Sharing Group。
  • 避免过度共享: 如果某个算子存在长尾计算(如复杂窗口聚合),独占槽可以避免影响其他算子的延迟。
常见误区: 并行度不等于任务槽数。并行度是逻辑概念,任务槽是物理资源。即使并行度设为 100,如果集群只有 10 个任务槽,实际同时运行的子任务也只有 10 个,其余 90 个会排队等待。

2.5 组件交互流程(作业提交到执行)

  1. 客户端提交: Client 将作业的 JobGraph 提交给 JobManager。
  2. JobManager 解析: JobManager 将 JobGraph 转换为 ExecutionGraph,确定并行度与任务分配。
  3. 资源申请: JobManager 向 ResourceManager 请求足够的任务槽。
  4. 任务分发: ResourceManager 分配空闲的 TaskManager 槽位,JobManager 将子任务部署到对应槽中。
  5. 数据执行: TaskManager 启动子任务线程,开始处理数据流,并通过网络进行 Shuffle 数据交换。
  6. 检查点协调: JobManager 定期触发 Checkpoint,TaskManager 将状态快照写入持久化存储。