文章目录
- 核心组件
- Client
- Dispatcher
- ResourceManager
- JobMaster
- TaskManager
- 任务提交流程
- yarn平台提交流程
- CliFrontend.java
- YarnJobClusterEntrypoint.java
- YarnTaskExecutorRunner.java
- 任务调度原理
- 问题
- 并行度
- slot
- Tasks
- 算子链
- slot共享
- 并行子任务分配
核心组件
Client
客户端用于执行程序的简单命令行前端的实现
注:是一个独立的进程,由用户启动
- 负责加载用户的程序,并且将相关依赖提交至HDFS
- 负责将JobGraph提交至Yarn的ResourceManager
Dispatcher
分发器负责接收作业提交,将其持久保存,产生JobManager来执行作业并在主失败的情况下恢复它们。此外,它了解Flink会话群集的状态。
注:是一个线程,由ApplicationMaster(JobManager)启动
- 负责启动Flink运行时的WebUI,监控集群运行状态
- 启动JobMaster
ResourceManager
资源管理器负责资源的取消/分配和注册
注:是一个线程,由ApplicationMaster(JobManager)启动
- 与Yarn的ResourceManager进行资源调度,获取可用资源
- 与Yarn的NodeManager沟通启动TaskManager
- 使用SlotManager管理TaskManager的slot
- 与JobManager沟通,将可用slot分发给JobManager
JobMaster
作业管理器主管负责执行单个JobGraph
注:是一个线程,由Dispatcher启动
- 与Flink的ResourceManager进行沟通,申请资源
- 维护内部slotPool
- 将Task分发至可用slot
- 作业过程中与TaskManager进行沟通与调度
TaskManager
作业管理器负责执行作业流的 task,并且缓存和交换数据流
注:是一个独立的进程
- 执行JobManger分配过来的任务
- 与其他TaskManager相互通信与传输数据
任务提交流程
yarn平台提交流程
提交的时候创建集群
主要的进程为Client,Yarn的ApplicationMaster(Flink的JobManager),TaskManager,ResourceManager
CliFrontend.java
- 参数解析
- 配置的封装
- 执行用户代码: execute()
- 生成StreamGraph
- Executor: 生成JobGraph
- 集群描述器: 上传jar包, 配置, 封装提交给yarn的命令
- yarnClient向Yarn的ResourceManager提交应用
YarnJobClusterEntrypoint.java
- Dispatcher的创建和启动
- ResourceManager的创建, 启动: slotManager(真正管理资源的, 向yarn申请资源)
- Dispatcher启动JobMaster(里面有一个slotPool, 真正发送请求的)
- slotPool向slotManager申请资源, slotManager向resourceManager申请资源(启动TM节点)
YarnTaskExecutorRunner.java
- 启动TaskExecutor
- 向Flink的RM注册slot
- RM分配slot
- TaskExecutor接收到分配的指令, 给JobMaster的slotPool
- JobMaster提交任务给TaskExecutor
任务调度原理
问题
- 怎样实现并行计算
slot - 一个流处理程序, 到底包含多少个任务
task和算子链 - 并行的任务, 需要占用多少slot
slot共享
并行度
并行任务执行的程度
算子的并行度: 一个任务的子任务并行的个数
任务的并行度: 所有算子中最大的并行的个数
slot
每个 task slot 代表 TaskManager 中资源的固定子集。例如,具有 3 个 slot 的 TaskManager,会将其托管内存 1/3 用于每个 slot。分配资源意味着 subtask 不会与其他作业的 subtask 竞争托管内存,而是具有一定数量的保留托管内存。注意此处没有 CPU 隔离;当前 slot 仅分离 task 的托管内存。
Flink任务执行的最小执行资源(划分内存资源, CPU共享), 代表着最大的并行能力 - 彼此内存资源隔离, 互不影响
Tasks
算子链
数据之间的传输形式
对于分布式执行,Flink 将算子的 subtasks 链接成 tasks。每个 task 由一个线程执行。
如果按照上图中所表示的一个task一个slot的话, 那么需要7个slot
- 一个算子可能会有不同的并行度
- 算子之间传输数据的形式可以是one-to-one,也可以是redistributing,具体是哪一类,需要看算子的类型
将两个算子链接在一起能使得它们在同一个线程中执行,从而提升性能。
- 减少线程间切换、缓冲的开销
- 减少延迟的
- 增加整体吞吐量
经过算子链优化之后,需要5个slot
Flink 默认会将能链接的算子尽可能地进行链接(例如, 两个 map 转换操作)。此外,Flink 还提供了对链接更细粒度控制的 API 以满足更多需求:
slot共享
特定条件的多个task可以在一个slot里面
上面图中的任务需要5个slot,可是在Flink运行的时候,其实用不了这么多slot,下面看看是如何优化的
前后发生的不同的任务, 可以共享slot,经过优化只需要2个slot
共享slot的优势
- 一个slot里面就可以保存整个管道
- 容灾(假如一个挂了, 重启当前slot即可)
- 减少网络间shuffle
- 负载均衡(有些算子是计算密集, 有些是非密集, 不负载的话, 密集计算有可能忙的忙死, 闲的闲死)
并行子任务分配