2. Flink 架构与组件:运行时架构、JobManager、TaskManager、任务槽与并行度
Flink 的运行时架构采用经典的 主从(Master-Worker) 模型,核心组件包括 JobManager(主节点)和 TaskManager(工作节点)。理解这些组件的职责、交互方式以及任务槽与并行度的关系,是掌握 Flink 实时额度计算性能调优的基础。
2.1 Flink 运行时架构总览
Flink 集群启动后,JobManager 负责接收作业、生成执行计划、协调检查点;TaskManager 负责实际执行算子任务。客户端(Client)仅负责提交作业,不参与运行时计算。
核心原则: JobManager 是“大脑”,TaskManager 是“肌肉”。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 共享一个槽 |
2.4 任务槽配置最佳实践
- 推荐槽数: 每个 TaskManager 设置 1~8 个任务槽,具体取决于 CPU 核心数和内存大小。通常建议槽数 = CPU 核心数。
- Slot Sharing 策略: 对于额度计算中的轻量算子(如 Map、Filter),开启 Slot Sharing 可显著提高资源利用率;对于重量算子(如大状态 KeyBy 窗口),建议单独分配 Slot Sharing Group。
- 避免过度共享: 如果某个算子存在长尾计算(如复杂窗口聚合),独占槽可以避免影响其他算子的延迟。
常见误区: 并行度不等于任务槽数。并行度是逻辑概念,任务槽是物理资源。即使并行度设为 100,如果集群只有 10 个任务槽,实际同时运行的子任务也只有 10 个,其余 90 个会排队等待。
2.5 组件交互流程(作业提交到执行)
- 客户端提交: Client 将作业的 JobGraph 提交给 JobManager。
- JobManager 解析: JobManager 将 JobGraph 转换为 ExecutionGraph,确定并行度与任务分配。
- 资源申请: JobManager 向 ResourceManager 请求足够的任务槽。
- 任务分发: ResourceManager 分配空闲的 TaskManager 槽位,JobManager 将子任务部署到对应槽中。
- 数据执行: TaskManager 启动子任务线程,开始处理数据流,并通过网络进行 Shuffle 数据交换。
- 检查点协调: JobManager 定期触发 Checkpoint,TaskManager 将状态快照写入持久化存储。