InfoQ深入浅出Spark(三):Spark调度系统之“权力的游戏”( 四 )


InfoQ深入浅出Spark(三):Spark调度系统之“权力的游戏”
本文插图
FIFOSchedulableBuilder 的处理逻辑相当简单 , 首先对于调度池的构建 , 它不需要做任何事 , 仅仅是获得构造方法中传进来的调度池的引用而已;addTaskSetManager 也仅仅是根据“先到先得”的原则向队列中追加 TaskSetManager , 这也是 FIFO 名字的由来 。
FairSchedulableBuilder 需要做的事情则复杂得多 , 对于调度池构建 , 它需要读取 fairscheduler.xml(或自定义配置文件)中关于层级队列的配置来对应地创建层级嵌套的队列结构;添加 TaskSetManager 的逻辑也会麻烦一些 , 首先需要找到插入该 TaskSetManager 的目标队列 , 如果不存在还需另行创建并把该队列追加到已有的层级队列中 , 然后再把 TaskSetManager 塞入到该目标队列 。
顾名思义 , Fair 是公平的意思 , 之所以称为公平调度 , 是因为FairSchedulableBuilder 所依赖的 fairscheduler.xml 规范文件将分布式集群计算资源按照层级嵌套的规则划分为多个子集 , 每个子集都根据一组参数划定可以占用的计算资源配额 。
具体来说 , 在 FairSchedulableBuilder 中 , 有两个关键参数用于划定计算资源配比 , 即 weight、minShare 。
InfoQ深入浅出Spark(三):Spark调度系统之“权力的游戏”
本文插图
我们以 Apache Spark 官网给出的 fairscheduler.xml 为例 , 该示例定义了 3 个调度池 , 3 个调度池之间的关系是采用公平的方式按照配额划分计算资源 。 这里 3 个调度池的 weight 都是 1(最后一个没有指定 weight 则采用默认值) , minShare 指定每个调度池所必需的最小 CPU 个数 , 如果没有指定 , 默认为 1 。 有意思的是 , 每个调度池还可以指定自己内部的调度模式 , 在这个例子中 , 3 个调度池内部的调度算法都是 FIFO , 也就是说 , 虽然 3 个调度池之间是“公平”地抢占资源 , 但是在各个调度池内部 , 还是按照先到先得的原则来调度任务 。
InfoQ深入浅出Spark(三):Spark调度系统之“权力的游戏”
本文插图
例子来源:https://github.com/apache/spark/blob/master/core/src/test/resources/fairscheduler.xml相比塔斯克 , 拜肯德老板的下属要忠心的多 , ExecutorBackend 作为拜肯德的唯一下属 , 远远地戍守在分公司 , 定期向老板汇报分公司的人力资源状态 。 由于离权力中心较远 , ExecutorBackend 对于老大的地位构不成任何威胁 , 也正因为如此 , 拜肯德对于小弟 ExecutorBackend 可以说是充分放权 , 能下放的事情尽量下放 , 自己则稳坐高阁、逍遥自在 。
InfoQ深入浅出Spark(三):Spark调度系统之“权力的游戏”
本文插图
元老派人员构成空降派面对根深蒂固的元老派 , 戴格作为职场老手自然也不会光杆司令一个人单打独挑 。 在入职总公司的当天 , 戴格即将自己多年的亲信 EventProcessLoop 招致麾下 。 EventProcessLoop 作为贴身秘书 , 对于戴格的想法和意图心领神会 , 对于戴格的处境更是心照不宣 。 自合作以来 , EventProcessLoop 一直扮演着老黄牛的角色 , 按部就班、有条不紊地执行老板交代的一项又一项任务 , 戴格对其自然信任有加 , 手里的大小事务几乎都交由 EventProcessLoop 代理 。
InfoQ深入浅出Spark(三):Spark调度系统之“权力的游戏”
本文插图
DAGScheduler 与 EventProcessLoop 之间的方法调用每当 DAGScheduler 有新事件(DAGSchedulerEvent)需要处理时 , 都会调用 EventProcessLoop 的 post 方法将其塞入 EventProcessLoop 的无限长阻塞队列 。 EventProcessLoop 的异步单线程以循环的方式(Loop 命名的由来)不断从队首读取并消费事件 , 通过调用与事件对应的方法(由 DAGScheduler 提供)来执行相应的任务 。