大数据 -109 Flink 架构深度解析:JobManager、TaskManager 与核心角色全景图

点一下关注吧!!!非常感谢!!持续更新!!!
🚀 AI 篇持续更新中!(长期更新)
AI 炼丹日志-31- 千呼万唤始出来 GPT-5 发布!“快的模型 + 深度思考模型 + 实时路由”,持续打造实用 AI 工具指南!📐🤖
💻 Java 篇正式开启!(300 篇)
目前 2025 年 09 月 22 日更新到:Java-130 深入浅出 MySQL MyCat 深入解析 核心配置文件 server.xml 使用与优化 MyBatis 已完结,Spring 已完结,Nginx 已完结,Tomcat 已完结,分布式服务正在更新!深入浅出助你打牢基础!
📊 大数据板块已完成多项干货更新(300 篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT 案例 详解

章节内容
上节完成了如下的内容:
Flink 批处理介绍
Flink 单词统计 Word Count

Flink 的重要角色及其工作原理
Flink 确实采用了经典的 Master/Slave 架构设计,这种架构模式在大数据处理系统中非常常见。下面详细介绍 Flink 中的核心角色及其功能:
1. JobManager(Master 节点)
JobManager 作为集群的管理者,承担着以下关键职责:
1.1 任务协调与管理
任务调度:负责将用户提交的任务分解为具体的 Task,并分配给各个 TaskManager 执行。例如,当用户提交一个流处理作业时,JobManager 会将其分解为 Source、Transformation 和 Sink 等操作,并映射到具体的 Task。
检查点协调:定期触发检查点(CheckPoint)机制,确保流处理的一致性。例如,在 Exactly-Once 语义下,JobManager 会协调所有 TaskManager 同时保存状态快照。
故障恢复:当 TaskManager 发生故障时,JobManager 负责从最近的检查点恢复任务状态,重新调度受影响的任务。
1.2 高可用设计
主备模式:在生产环境中,通常配置多个 JobManager 实例。其中:
一个作为 Leader:负责处理所有客户端请求和任务管理
其他作为 Standby:保持与 Leader 同步,当 Leader 失效时通过选举机制接管
选举机制:通常基于 ZooKeeper 实现 Leader 选举,确保单点故障时能快速恢复
1.3 应用接收
JobManager 支持两种主要的应用提交方式:
Jar 包方式:用户将完整的 Flink 应用打包成 Jar 文件提交
JobGraph 方式:用户直接提交已构建好的任务拓扑图(JobGraph)
例如,通过命令行提交时可以使用:
2. TaskManager(Slave 节点)
TaskManager 是实际执行任务的 Worker 节点:
每个 TaskManager 包含一定数量的 Task Slot,用于执行具体的 Task
负责数据缓冲、网络传输等底层操作
向 JobManager 定期发送心跳,汇报状态和资源使用情况
3. 交互流程示例
一个典型的作业执行流程如下:
客户端提交作业到 JobManager
JobManager 解析作业,生成执行计划
JobManager 向 ResourceManager 申请资源
TaskManager 注册到 JobManager 并提供可用 Slot
JobManager 将 Task 部署到 TaskManager 的 Slot 中
TaskManager 开始执行任务并定期向 JobManager 汇报状态
这种架构设计使 Flink 能够高效地处理大规模数据流,同时保证系统的可靠性和容错能力。
TaskManager(Slave)
也称为 Worker
主要职责是从 JobManager 处接收任务,并部署和启动任务,接收上游的数据处理
TaskManager 是在 JVM 中的一个或者多个线程中执行任务的工作节点
TaskManager 是在 JVM 中的一个或多个线程中执行任务的工作节点
TaskManager 在启动的时候会向 ResourceManager 注册自己的资源信息(Slot 数量相等)
角色与功能
任务执行:TaskManager 是 Flink 集群中执行分布式数据处理任务的核心组件。它接收 JobManager 分发的任务,执行具体的计算,并将结果返回给 JobManager 或下一个处理节点。
资源管理:TaskManager 管理分配给它的计算资源(如 CPU、内存)。Flink 中,每个 TaskManager 都有一个或多个 Slot,每个 Slot 可以执行一个并行子任务(Subtask)。Slot 是 Flink 任务资源调度的基本单元。
数据交换与缓存:TaskManager 负责不同任务之间的数据交换,如 Shuffle 操作,并且会对数据进行缓存以提高计算效率。
启动与运行
注册到 JobManager:TaskManager 启动时,会向 JobManager 注册自己,报告自身的可用资源信息(如可用内存和 Slot 数量)。JobManager 通过这些信息进行任务的调度和资源分配。
执行任务:当 JobManager 将任务分配给 TaskManager 后,TaskManager 会启动相应的 Task,并持续监控它的执行状态。任务完成后,TaskManager 将结果汇报给 JobManager。
故障处理:TaskManager 具备一定的故障恢复能力。如果在任务执行过程中发生故障,TaskManager 会向 JobManager 报告,JobManager 根据需要重新分配任务。
通信机制
网络通信:TaskManager 通过网络与其他 TaskManager 和 JobManager 进行通信,交换中间结果数据。Flink 提供高效的网络堆栈来支持低延迟和高吞吐量的分布式数据流处理。
RPC 与心跳机制:TaskManager 和 JobManager 之间通过 RPC(远程过程调用)进行交互,并通过心跳机制确保 TaskManager 的健康状态。如果 JobManager 在一段时间内没有收到 TaskManager 的心跳,则可能认为该 TaskManager 已不可用,并触发故障恢复流程。
监控与日志
监控:Flink 提供了多种监控 TaskManager 运行状态的方式,如 Web 界面、日志文件和指标(Metrics)系统。管理员可以通过这些工具监控每个 TaskManager 的资源使用情况、任务执行进度和性能瓶颈。
日志:TaskManager 会记录日志文件,详细描述任务执行情况和出现的错误。这些日志对排查问题和调优系统非常重要。
ResourceManager
针对不同的环境和资源提供者,如(YRAN、Kubernetes、独立部署),Flink 提供了不同的 ResourceManager。它的作用是负责管理 Flink 的处理资源单元(Slot)
角色与功能
资源管理:ResourceManager 负责管理整个集群的计算资源,包括 CPU、内存、和网络资源。它接收来自 JobManager 的资源请求,并调度和分配这些资源,以启动必要数量的 TaskManager 实例。
资源请求与分配:当 Flink 应用程序启动时,JobManager 会向 ResourceManager 请求所需的资源,ResourceManager 根据集群的资源状况来分配或启动 TaskManager 实例,以满足这些需求。
资源回收:在任务完成后,ResourceManager 负责回收和释放这些资源,使它们可以被其他任务再次利用。
与 JobManager 的协作
资源调度:JobManager 会根据作业的并行度和资源需求生成任务计划,并将这些需求发送给 ResourceManager。ResourceManager 负责根据集群的资源情况来决定如何分配这些资源。
启动 TaskManager:如果当前集群中可用的 TaskManager 无法满足 JobManager 的需求,ResourceManager 会启动新的 TaskManager 实例来处理任务。这通常通过集成的资源管理平台(如 Yarn、Kubernetes 或 Mesos)来完成。
资源监控
资源使用情况监控:ResourceManager 监控整个集群的资源使用情况,包括 CPU、内存、和网络带宽的利用率。这些监控数据可以帮助管理员优化资源分配和调度策略。
日志和指标:ResourceManager 生成详细的日志文件,记录资源请求、分配、回收等操作。此外,Flink 还提供了多种监控工具,可以实时查看 ResourceManager 的运行状态和资源使用情况。
Dispatcher
它的作用是提供一个 REST 接口来让我们提交需要执行的应用。一旦一个应用提交执行,Dispatcher 会启动一个 JobManager,并将应用转交给它。Dispatcher 还会启动一个 WebUI 来提供有关作业作业执行信息注意:某些应用的提交执行的方式,有可能用不到 Dispatcher
角色与功能
作业提交与调度:Dispatcher 负责接收来自客户端的作业提交请求。每当一个作业被提交时,Dispatcher 会启动一个新的 JobManager 实例来管理这个作业的执行。这种设计确保了作业之间的隔离,防止一个作业的失败影响到其他作业。
多作业管理:Dispatcher 可以同时管理多个作业。每个作业都有独立的 JobManager 实例,Dispatcher 负责监控这些作业的状态,并在作业完成或失败后回收资源。
REST 接口:Dispatcher 提供一个 RESTful 接口,允许用户通过 HTTP 请求提交、查询和管理作业。这使得 Flink 可以与其他系统更容易地集成,并简化了自动化作业调度的实现。
与 JobManager 的关系
独立 JobManager:在 Dispatcher 负责的架构下,每个提交的作业都会启动一个独立的 JobManager 实例。这样做的好处是每个作业都是隔离运行的,这提升了集群的稳定性和健壮性。
任务调度:Dispatcher 在收到作业提交请求后,首先决定如何分配资源并启动相应的 JobManager,然后由这个 JobManager 来管理和调度 TaskManager 上的具体任务执行。
架构与组件交互
资源管理交互:Dispatcher 并不直接管理集群的资源,而是依赖于 ResourceManager 来提供和调度所需的资源。在作业提交时,Dispatcher 向 ResourceManager 请求启动 JobManager 和 TaskManager 实例。
与客户端交互:Dispatcher 是客户端提交作业的入口点。客户端通过 REST API 与 Dispatcher 通信,提交作业、取消作业或查询作业状态。Dispatcher 负责将这些请求分发到对应的 JobManager。
各个组件之间关系

Flink 运行架构
Flink 程序结构
Flink 程序的基本构建块是流和转换(请注意,Flink 和 DataSet API 中使用的 Dataset 也是内部流)。从概念上讲,流是(可能永远无止境的)数据记录流,而转换是将一个或者多个流输入,并产生一个或多个输出流。

上图表述了 Flink 的应用程序结构,有 Source(源头)、Transformation(转换)、Sink(接收器)三个重要的组成部分。
Source
数据源,定义 Flink 从哪里加载数据,Flink 在流处理和批处理上的 Source 大概有 4 类:
基于本地集合的 Source
基于文件的 Source
基于网络套接字的 Source
自定义的 Source(Apache Kafka、RabbitMQ 等)
Transformation
数据转换的各种操作,也称为算子,有 Map、FlatMap、Filter、KeyBy、Reduce、Window 等,可以将数据转换计算成你想要的数据。
Sink
接收器,Flink 将转换计算后的数据发送的地点,定义了结果数据的输出方向,Flink 常见的 Sink 大概有这么几类:
写入文件
打印出来
写入 Socket
自定义 Sink(Apache Kafka、RabbitMQ、MySQL、Elasticsearch、HDFS 等)
Task 和 SubTask
Task 是一个阶段多个功能相同的 SubTask 集合,类似于 Spark 中的 TaskSet
SubTask(子任务)是 Flink 中任务最小的执行单元,是一个 Java 类的实例,这个 Java 类中有属性和方法,完成具体的计算逻辑。比如执行一个操作 map,分布式场景下会有多个线程中同时执行,每个线程中执行的都叫一个 SubTask。
OperatorChain
Flink 的所有操作都叫做 Operator,客户端在提交任务的时候会对 Operator 进行优化操作,能进行合并的 Operator 会被合并为一个 Operator,合并后的 Operator 成为 OperatorChain,实际上就是一个执行链,每个执行链会在 TaskManager 上一个独立的线程中执行。

Flink 中的数据传输
在运行过程中,应用中的任务会持续进行数据交换。为了有效利用网络资源和提高吞吐量,Flink 在处理任务的数据传输过程中,采用了缓冲机制。
任务槽和槽共享
任务槽也叫做 Task-Slot,槽共享也叫 Slot-Sharing

每个 TaskManager 是一个 JVM 的进程,可以在不同的线程中执行一个或多个子任务。为了控制一个 Worker 能接收多少个 Task,Worker 通过 TaskSlot 来进行控制(一个 Worker 至少有一个 TaskSlot)
任务槽
每个 TaskSlot 表示 TaskManager 拥有资源的一个固定大小的子级,一般来说:我们分配的槽的个数都是 CPU 的核数相等,比如 6 核,那就分配 6 个槽。Flink 将进程的内存进行了划分到多个 Slot 中,假设一个 TaskManager 机器有 3 个 Slot,那么每个 Slot 占 1/3 的内存(平均分配)。
内存被划分到不同的 Slot 之后可以得到的好处如下:
TaskManager 最多能同时并发执行的任务是可以控制的,那就是 3 个,因为不能超过 Slot 的数量。
Slot 有独占的内存空间,这样在一个 TaskManager 中可以运行多个不同的作业,作业之间不受影响。
槽共享
默认情况下,Flink 允许子任务 subtask(map[1] map[2] keyby[1] keyby[2])共享插槽,即使他们是不同的任务的子任务,只要他们来自同一个作业。结果是一个槽可以保存作业的整个管道。

版权声明: 本文为 InfoQ 作者【武子康】的原创文章。
原文链接:【http://xie.infoq.cn/article/5aca702d93acc9076ba82e7c8】。文章转载请联系作者。
评论