Volcano 成 Spark 默认 batch 调度器
2022 年 6 月 16 日,Apache Spark 3.3 版本正式发布,其中《Support Customized Kubernetes Schedulers》作为 Spark 3.3 版本的重点(Highlight)特性,其关键能力是从框架层面支持定制化的 Kubernetes 度器,并且将 Volcano 作为 Spark on Kubernetes 的默认 batch 调度器。这也是 Apache Spark 社区官方支持 Volcano 的第一个版本。对于 Spark 用户而言,借助 Volcano 提供的批量调度、细粒度资源管理等功能,可以更便捷的从 Hadoop 迁移到 Kubernetes,同时大幅提升大规模数据分析业务的性能。
华为牵头发起,主流厂商协作
该特性由华为牵头发起,由来自华为、Apple、Cloudera、Netflix、Databricks 等公司的开发者共同协作完成。通过在 Apache Spark 支持自定义调度能力,允许用户插件化使用各种第三方自定义调度。
Spark + Volcano:更完善的调度能力
Spark 的资源管理平台正在向 Kubernetes 演进,Apache Spark 现有架构下,Job 的单主、多从节点的分离调度,导致了 Spark driver 节点资源死锁问题,尤其是在资源紧张的情况下,会经常出现此类问题。同时,由于原生 Kubernetes 的调度能力受限,也无法完成 Job 粒度诸如队列调度、公平调度、资源预留等功能。
Volcano 作为 CNCF 社区首个云原生批量计算,于 2019 年 6 月在上海 KubeCon 正式开源,并在 2020 年 4 月成为 CNCF 官方项目。2022 年 4 月,Volcano 正式晋级为 CNCF 孵化项目。Volcano 社区开源以来,在人工智能、大数据、基因测序、转码、渲染等海量数据计算和分析场景得到快速应用,并构建起完善的上下游生态,目前腾讯、爱奇艺、小红书、蘑菇街、唯品会、鹏程实验室、锐天投资等企业均将 Volcano 应用于生产环境。
Spark 官方支持 Volcano 将会进一步加速大数据平台迁移到 Kubernetes 的进程,帮助 Spark 用户应对以下常见的批量调度场景。
常见调度场景:
作业级的公平调度 (Job-based Fair-share)
当运行多个弹性作业(如流媒体分析)时,需要公平地为每个作业分配资源,以满足多个作业竞争附加资源时的 SLA/QoS 要求。在最坏的情况下,单个作业可能会启动大量的 pod 资源利用率低,从而阻止其他作业由于资源不足而无法运行。为了避免分配过小(例如,为每个作业启动一个 Pod),Volcano 允许弹性作业定义应该启动的 Pod 的最小可用数量。 超过指定的最小可用量的任何 pod 都将公平地与其他作业共享集群资源。
队列 (Queue)
队列还广泛用于共享弹性工作负载和批处理工作负载的资源。队列的主要目的是:
在不同的“租户”或资源池之间共享资源,例如将每一个部门映射到一个队列,实现多个部门通过队列的权重,动态共享集群的资源。
为不同的“租户”或资源池支持不同的调度策略或算法,如 FIFO、Fairness、Priority 等
队列被实现为集群范围的 CRD,和 namespace 实现了解耦。这允许将在不同 namespace 中创建的作业放置在一个共享队列中。队列还提供了 min 和 max,min 是队列的最小保障资源,任何时刻该队列有紧急任务提上来都保证有 min 资源可用,max 是队列资源使用上限。min 和 max 之间的资源如果闲置,允许共享给其他队列的任务来提升整体的资源利用率。
面向用户的, 跨队列的公平调度 (Namespace-based fair-share Cross Queue)
在队列中,每个作业在调度循环期间有几乎相等的调度机会,这意味着拥有更多作业的用户有更大的机会安排他们的作业,这对其他用户不公平。 例如,有一个队列包含少量资源,有 10 个 pod 属于 UserA,1000 个 pod 属于 UserB。在这种情况下,UserA 的 pod 被绑定到节点的概率较小。
为了平衡同一队列中用户之间的资源使用,需要更细粒度的策略。考虑到 Kubernetes 中的多用户模型,使用名称空间来区分不同的用户, 每个命名空间都将配置一个权重,作为控制其资源使用优先级的手段。
抢占 (Preemption & Reclaim)
通过公平分享来支持借贷模型,一些作业/队列在空闲时会过度使用资源。但是,如果有任何进一步的资源请求,资源“所有者”将“收回”。 资源可以在队列或作业之间共享:回收用于队列之间的资源平衡,抢占用于作业之间的资源平衡。
最小资源预留(minimal resource reservation)
运行拥有多个任务角色的作业时(如 Spark)时,Spark driver pod 会先创建并运行,然后请求 Kube-apiserver 创建 Spark executor pod,在资源紧张或高并发的场景,时常会出现大量作业提交导致所有可用资源被 Spark driver pod 耗尽,Spark executor 无法获取资源,最终所有 Spark 作业无法正常运行。为解决此问题,用户为 Spark driver pod 和 executor pod 创建专有节点进行静态划分,而这带来了资源碎片、利用率低下的问题。Volcano 提供的 minimal resource reservation 允许为每个 Spark 作业预留资源,防止 Spark executor 无法获取资源而导致的死锁问题,相比于静态划分的作法,性能提升 30%+。
预留与回填 (Reservation & Backfill)
当一个请求大量资源的“巨大”作业提交给 Kubernetes 时,当有许多小作业在管道中时,该作业可能会饿死,并最终根据当前的调度策略/算法被杀死。为了避免饥饿, 应该有条件地为作业保留资源,例如超时。当资源被保留时,它们可能会处于空闲和未使用状态。为了提高资源利用率,调度程序将有条件地将“较小”作业回填到那些保留资源中。 保留和回填都是根据插件的反馈触发的:Volcano 供了几个回调接口,供开发人员或用户决定哪些作业应该被填充或保留。
未来发展
随着场景的日益丰富,Volcano 也在不断的添加新的算法,同时,相应的接口也在不断的完善,方便用户扩展并自定义相应的算法。另一方面,社区也在持续的扩大技术版图支持新的场景如跨云跨集群调度、混部、FinOps、智能弹性调度、细粒度资源管理等。
近期我们还会对 Spark 3.3 中 Volcano 带来的批量调度能力进行详细技术解读,敬请期待。添加 Volcano 小助手 k8s2222,进入 Volcano 社区交流群,大咖在侧,定期分享。
Spark 3.3 release notes: https://spark.apache.org/releases/spark-release-3-3-0.html
Volcano 官网:https://volcano.sh/zh/docs/
Github : https://github.com/volcano-sh/volcano
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/892800239dd7ff6caf90040ab】。文章转载请联系作者。
评论