这是我参与「第四届青训营 」笔记创作活动的第9天
Gang 调度器
为什么要开发 Gang 调度器?
原生 YARN 的架构设计目标专注在离线 Batch 类计算作业上面,对于高吞吐追求极致,但是对于 latency 和全局约束上没有很好支持。流式/模型训练任务的出现,需求与 Batch 类相差较大, 当前YARN 的架构已经无法很好的满足这部分任务。目前 Flink 作业和模型训练类的作业在 YARN 上面运行, 在调度层面都遇到三个问题:
-
调度缺乏全局视角
-
单个 Application 调度过慢
-
Application 之间存在资源互锁情况
Gang 调度器有什么典型特点?
-
全局视角: 增加 YARN 调度时的全局视角
- 首先支持 Flink/GPU 训练的全局约束需求(负载均衡/ GPU 亲和性)
- 为未来更丰富的全局约束留出扩展空间
-
低延迟:
- 对于低 latency 需求的申请,在集群可以满足资源的条件时,1 次申请直接返回资源(ms级别)。
-
Gang性交付:
- 调度提供 all-or-nothing 的语义, 对于无法满足的申请直接返回失败, 对于可以满足的申请直接交付所有的申请资源,规避应用之间资源互锁的情况。
Gang 调度流程
-
选择 App
- 基于公平性策略对所有队列排序并选择一个队列;
- 基于公平性策略对队列内的任务排序并选择一个任务;
-
分配资源
-
强约束阶段:过滤掉不符合条件的节点
-
弱约束阶段:选择合适的节点分配资源(不排序,时间复杂度 O(n))
- Quota 平均:分配后节点已使用资源尽可能平均。总请求资源为 V1,总节点数为 N,已用资源为 U,节点目标资源为:S = (V1 + U)/N,遍历所有节点,每个节点分配 S - Un 即可;
- 跳过高 load 节点:优先往低 load 节点调度。满足 load 阈值节点 N1,不满足 N2,优先把 N1 剩余资源分配完,分配后未满足资源量为 V2,每个节点分配 V2/N2;
- 兜底分配
-
Gang Scheduler 调度与原生调度 Fair Scheduler 的关系
- 两个调度器会并存在 RM 中,当用户可以配置使用,默认使用原生调度器(Fair Scheduler)
- Gang Scheduler 不是一个完整的 Scheduler,它只负责决定哪个 container 被分配到哪台机器上,不负责完整的container生命周期管理,这些管理工作依然由Fair Scheduler负责
- 两种调度模式在调度资源时会争抢Node级别的锁,各自调度。
反调度器
为什么需要开发反调度器?
- 调度器的调度决策受“时空”限制
- 任务运行和集群状态高动态性
- 需要持续保证最初调度决策的正确性
任务配置的调度约束在运行过程中需要持续被满足
反调度流程
-
根据 AM 请求中的强约束,构造强约束集;
-
遍历强约束集选择不再符合强约束条件的节点;
-
遍历异常节点下的 Container,针对每个节点选择需要进行反调度的 Container,并添加至反调度 Container 列表中;
-
将反调度 Container 列表随心跳返回给对应AM;
反调度器与 Gang 调度器关系
反调度器与 Gang 调度器关系:是 Gang 调度器的“伴侣”
-
两者不同点
- 发挥作用的时机不同。调度器在资源请求到来时根据当前时刻集群信息进行资源分配。反调度器在任务运行过程中,检测出不再正确的调度决策并进行修正。
- 处理机制相反。调度器负责根据调度策略分配container到计算节点。反调度器负责根据反调度策略清理计算节点上的container。
-
两者联系
- 反调度器是调度器的修正和补充,在反调度器的恢复过程中需要通过调度器进行新container的申请,两者共同促进资源的合理分配。
单集群 50K 突破
为什么需要提升单集群规模?
-
更好的资源池化和资源共享
-
降低运维成本
提升单集群规模有哪些瓶颈点?
-
RPC 层: 接收请求、处理请求、返回结果
- RPC 处理时间 5ms,handler 默认 80 线程,消费吞吐约 16K/s,RPC server queue 容易打满
-
Dispatcher 层:将事件传递给对应的事件调度器
- 生产速率过大,AsyncDispatcher queue 容易 pending
- 消费速率过低,Scheduler 的 NODE_UPDATE 事件处理过慢
-
Scheduler 层:真正调度
- FSLeafQueue 分配单 Container 延迟太高,存在空转
单集群突破 50K
心跳反压机制:将 NM 节点的心跳机制改为根据 RM 的压力动态调整 ,当事件池中的事件超过阈值时调大心跳周期,当事件池中的事件小于阈值时调小心跳周期
- 多线程调度
- 事件精简
- 空转优化
- 内存单位优化
- 切主优化